AWT/Swing merge from GNU Classpath.
From-SVN: r56147
This commit is contained in:
parent
097684ce62
commit
7bde45b2eb
490 changed files with 86038 additions and 9753 deletions
556
libjava/java/awt/KeyboardFocusManager.java
Normal file
556
libjava/java/awt/KeyboardFocusManager.java
Normal file
|
@ -0,0 +1,556 @@
|
|||
/* KeyboardFocusManager.java -- manage component focusing via the keyboard
|
||||
Copyright (C) 2002 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package java.awt;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.beans.VetoableChangeListener;
|
||||
import java.beans.VetoableChangeSupport;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Eric Blake <ebb9@email.byu.edu>
|
||||
* @since 1.4
|
||||
* @status partially updated to 1.4, needs documentation.
|
||||
*/
|
||||
public abstract class KeyboardFocusManager
|
||||
implements KeyEventDispatcher, KeyEventPostProcessor
|
||||
{
|
||||
public static final int FORWARD_TRAVERSAL_KEYS = 0;
|
||||
public static final int BACKWARD_TRAVERSAL_KEYS = 1;
|
||||
public static final int UP_CYCLE_TRAVERSAL_KEYS = 2;
|
||||
public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3;
|
||||
|
||||
private static final Set DEFAULT_FORWARD_KEYS;
|
||||
private static final Set DEFAULT_BACKWARD_KEYS;
|
||||
static
|
||||
{
|
||||
Set s = new HashSet();
|
||||
s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0));
|
||||
s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
|
||||
KeyEvent.CTRL_DOWN_MASK));
|
||||
DEFAULT_FORWARD_KEYS = Collections.unmodifiableSet(s);
|
||||
s = new HashSet();
|
||||
s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
|
||||
KeyEvent.SHIFT_DOWN_MASK));
|
||||
s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,
|
||||
KeyEvent.SHIFT_DOWN_MASK
|
||||
| KeyEvent.CTRL_DOWN_MASK));
|
||||
DEFAULT_BACKWARD_KEYS = Collections.unmodifiableSet(s);
|
||||
}
|
||||
|
||||
private static KeyboardFocusManager current
|
||||
= new DefaultKeyboardFocusManager();
|
||||
|
||||
// XXX Not implemented correctly. I think a good implementation here may
|
||||
// be to have permanentFocusOwner be null, and fall back to focusOwner,
|
||||
// unless a temporary focus change is in effect.
|
||||
private static Component focusOwner;
|
||||
private static Component permanentFocusOwner;
|
||||
|
||||
private static Window focusedWindow;
|
||||
private static Window activeWindow;
|
||||
private static Container focusCycleRoot;
|
||||
|
||||
private FocusTraversalPolicy defaultPolicy;
|
||||
private Set[] defaultFocusKeys = new Set[] {
|
||||
DEFAULT_FORWARD_KEYS, DEFAULT_BACKWARD_KEYS,
|
||||
Collections.EMPTY_SET, Collections.EMPTY_SET
|
||||
};
|
||||
|
||||
private final PropertyChangeSupport propertyChangeSupport
|
||||
= new PropertyChangeSupport(this);
|
||||
private final VetoableChangeSupport vetoableChangeSupport
|
||||
= new VetoableChangeSupport(this);
|
||||
private final ArrayList keyEventDispatchers = new ArrayList();
|
||||
private final ArrayList keyEventPostProcessors = new ArrayList();
|
||||
|
||||
|
||||
public KeyboardFocusManager()
|
||||
{
|
||||
}
|
||||
|
||||
public static KeyboardFocusManager getCurrentKeyboardFocusManager()
|
||||
{
|
||||
// XXX Need a way to divide this into contexts.
|
||||
return current;
|
||||
}
|
||||
|
||||
public static void setCurrentKeyboardFocusManager(KeyboardFocusManager m)
|
||||
{
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null)
|
||||
sm.checkPermission(new AWTPermission("replaceKeyboardFocusManager"));
|
||||
// XXX Need a way to divide this into contexts.
|
||||
current = m == null ? new DefaultKeyboardFocusManager() : m;
|
||||
}
|
||||
|
||||
public Component getFocusOwner()
|
||||
{
|
||||
// XXX Need an easy way to test if this thread is in the context of the
|
||||
// global focus owner, to avoid creating the exception in the first place.
|
||||
try
|
||||
{
|
||||
return getGlobalFocusOwner();
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Component getGlobalFocusOwner()
|
||||
{
|
||||
// XXX Need a way to test if this thread is in the context of the focus
|
||||
// owner, and throw a SecurityException if that is the case.
|
||||
// XXX Implement.
|
||||
return focusOwner;
|
||||
}
|
||||
|
||||
protected void setGlobalFocusOwner(Component owner)
|
||||
{
|
||||
// XXX Should this send focus events to the components involved?
|
||||
if (owner == null || owner.focusable)
|
||||
{
|
||||
firePropertyChange("focusOwner", focusOwner, owner);
|
||||
try
|
||||
{
|
||||
fireVetoableChange("focusOwner", focusOwner, owner);
|
||||
focusOwner = owner;
|
||||
}
|
||||
catch (PropertyVetoException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearGlobalFocusOwner()
|
||||
{
|
||||
// XXX Is this enough?
|
||||
setGlobalFocusOwner(null);
|
||||
}
|
||||
|
||||
public Component getPermanentFocusOwner()
|
||||
{
|
||||
// XXX Need an easy way to test if this thread is in the context of the
|
||||
// global focus owner, to avoid creating the exception in the first place.
|
||||
try
|
||||
{
|
||||
return getGlobalPermanentFocusOwner();
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Component getGlobalPermanentFocusOwner()
|
||||
{
|
||||
// XXX Need a way to test if this thread is in the context of the focus
|
||||
// owner, and throw a SecurityException if that is the case.
|
||||
// XXX Implement.
|
||||
return permanentFocusOwner == null ? focusOwner : permanentFocusOwner;
|
||||
}
|
||||
|
||||
protected void setGlobalPermanentFocusOwner(Component focusOwner)
|
||||
{
|
||||
// XXX Should this send focus events to the components involved?
|
||||
if (focusOwner == null || focusOwner.focusable)
|
||||
{
|
||||
firePropertyChange("permanentFocusOwner", permanentFocusOwner,
|
||||
focusOwner);
|
||||
try
|
||||
{
|
||||
fireVetoableChange("permanentFocusOwner", permanentFocusOwner,
|
||||
focusOwner);
|
||||
permanentFocusOwner = focusOwner;
|
||||
}
|
||||
catch (PropertyVetoException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Window getFocusedWindow()
|
||||
{
|
||||
// XXX Need an easy way to test if this thread is in the context of the
|
||||
// global focus owner, to avoid creating the exception in the first place.
|
||||
try
|
||||
{
|
||||
return getGlobalFocusedWindow();
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Window getGlobalFocusedWindow()
|
||||
{
|
||||
// XXX Need a way to test if this thread is in the context of the focus
|
||||
// owner, and throw a SecurityException if that is the case.
|
||||
// XXX Implement.
|
||||
return focusedWindow;
|
||||
}
|
||||
|
||||
protected void setGlobalFocusedWindow(Window window)
|
||||
{
|
||||
// XXX Should this send focus events to the windows involved?
|
||||
if (window == null || window.focusable)
|
||||
{
|
||||
firePropertyChange("focusedWindow", focusedWindow, window);
|
||||
try
|
||||
{
|
||||
fireVetoableChange("focusedWindow", focusedWindow, window);
|
||||
focusedWindow = window;
|
||||
}
|
||||
catch (PropertyVetoException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Window getActiveWindow()
|
||||
{
|
||||
// XXX Need an easy way to test if this thread is in the context of the
|
||||
// global focus owner, to avoid creating the exception in the first place.
|
||||
try
|
||||
{
|
||||
return getGlobalActiveWindow();
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Window getGlobalActiveWindow()
|
||||
{
|
||||
// XXX Need a way to test if this thread is in the context of the focus
|
||||
// owner, and throw a SecurityException if that is the case.
|
||||
// XXX Implement.
|
||||
return activeWindow;
|
||||
}
|
||||
|
||||
protected void setGlobalActiveWindow(Window window)
|
||||
{
|
||||
// XXX Should this send focus events to the windows involved?
|
||||
firePropertyChange("activeWindow", activeWindow, window);
|
||||
try
|
||||
{
|
||||
fireVetoableChange("activeWindow", activeWindow, window);
|
||||
activeWindow = window;
|
||||
}
|
||||
catch (PropertyVetoException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public FocusTraversalPolicy getDefaultFocusTraversalPolicy()
|
||||
{
|
||||
if (defaultPolicy == null)
|
||||
defaultPolicy = new DefaultFocusTraversalPolicy();
|
||||
return defaultPolicy;
|
||||
}
|
||||
|
||||
public void setDefaultFocusTraversalPolicy(FocusTraversalPolicy policy)
|
||||
{
|
||||
if (policy == null)
|
||||
throw new IllegalArgumentException();
|
||||
firePropertyChange("defaultFocusTraversalPolicy", defaultPolicy, policy);
|
||||
defaultPolicy = policy;
|
||||
}
|
||||
|
||||
public void setDefaultFocusTraversalKeys(int id, Set keystrokes)
|
||||
{
|
||||
if (keystrokes == null)
|
||||
throw new IllegalArgumentException();
|
||||
Set sa;
|
||||
Set sb;
|
||||
Set sc;
|
||||
String type;
|
||||
switch (id)
|
||||
{
|
||||
case FORWARD_TRAVERSAL_KEYS:
|
||||
sa = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
|
||||
sb = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
|
||||
sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
|
||||
type = "forwardDefaultFocusTraversalKeys";
|
||||
break;
|
||||
case BACKWARD_TRAVERSAL_KEYS:
|
||||
sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
|
||||
sb = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
|
||||
sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
|
||||
type = "backwardDefaultFocusTraversalKeys";
|
||||
break;
|
||||
case UP_CYCLE_TRAVERSAL_KEYS:
|
||||
sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
|
||||
sb = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
|
||||
sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS];
|
||||
type = "upCycleDefaultFocusTraversalKeys";
|
||||
break;
|
||||
case DOWN_CYCLE_TRAVERSAL_KEYS:
|
||||
sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS];
|
||||
sb = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS];
|
||||
sc = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS];
|
||||
type = "downCycleDefaultFocusTraversalKeys";
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
int i = keystrokes.size();
|
||||
Iterator iter = keystrokes.iterator();
|
||||
while (--i >= 0)
|
||||
{
|
||||
Object o = iter.next();
|
||||
if (! (o instanceof AWTKeyStroke)
|
||||
|| sa.contains(o) || sb.contains(o) || sc.contains(o)
|
||||
|| ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
keystrokes = Collections.unmodifiableSet(new HashSet(keystrokes));
|
||||
firePropertyChange(type, defaultFocusKeys[id], keystrokes);
|
||||
defaultFocusKeys[id] = keystrokes;
|
||||
}
|
||||
|
||||
public Set getDefaultFocusTraversalKeys(int id)
|
||||
{
|
||||
if (id < FORWARD_TRAVERSAL_KEYS || id > DOWN_CYCLE_TRAVERSAL_KEYS)
|
||||
throw new IllegalArgumentException();
|
||||
return defaultFocusKeys[id];
|
||||
}
|
||||
|
||||
public Container getCurrentFocusCycleRoot()
|
||||
{
|
||||
// XXX Need an easy way to test if this thread is in the context of the
|
||||
// global focus owner, to avoid creating the exception in the first place.
|
||||
try
|
||||
{
|
||||
return getGlobalCurrentFocusCycleRoot();
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Container getGlobalCurrentFocusCycleRoot()
|
||||
{
|
||||
// XXX Need a way to test if this thread is in the context of the focus
|
||||
// owner, and throw a SecurityException if that is the case.
|
||||
// XXX Implement.
|
||||
return focusCycleRoot;
|
||||
}
|
||||
|
||||
protected void setGlobalCurrentFocusCycleRoot(Container cycleRoot)
|
||||
{
|
||||
firePropertyChange("currentFocusCycleRoot", focusCycleRoot, cycleRoot);
|
||||
focusCycleRoot = cycleRoot;
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener l)
|
||||
{
|
||||
if (l != null)
|
||||
propertyChangeSupport.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener l)
|
||||
{
|
||||
if (l != null)
|
||||
propertyChangeSupport.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
public PropertyChangeListener[] getPropertyChangeListeners()
|
||||
{
|
||||
return propertyChangeSupport.getPropertyChangeListeners();
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(String name, PropertyChangeListener l)
|
||||
{
|
||||
if (l != null)
|
||||
propertyChangeSupport.addPropertyChangeListener(name, l);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(String name,
|
||||
PropertyChangeListener l)
|
||||
{
|
||||
if (l != null)
|
||||
propertyChangeSupport.removePropertyChangeListener(name, l);
|
||||
}
|
||||
|
||||
public PropertyChangeListener[] getPropertyChangeListeners(String name)
|
||||
{
|
||||
return propertyChangeSupport.getPropertyChangeListeners(name);
|
||||
}
|
||||
|
||||
protected void firePropertyChange(String name, Object o, Object n)
|
||||
{
|
||||
propertyChangeSupport.firePropertyChange(name, o, n);
|
||||
}
|
||||
|
||||
public void addVetoableChangeListener(VetoableChangeListener l)
|
||||
{
|
||||
if (l != null)
|
||||
vetoableChangeSupport.addVetoableChangeListener(l);
|
||||
}
|
||||
|
||||
public void removeVetoableChangeListener(VetoableChangeListener l)
|
||||
{
|
||||
if (l != null)
|
||||
vetoableChangeSupport.removeVetoableChangeListener(l);
|
||||
}
|
||||
|
||||
public VetoableChangeListener[] getVetoableChangeListeners()
|
||||
{
|
||||
return vetoableChangeSupport.getVetoableChangeListeners();
|
||||
}
|
||||
|
||||
public void addVetoableChangeListener(String name, VetoableChangeListener l)
|
||||
{
|
||||
if (l != null)
|
||||
vetoableChangeSupport.addVetoableChangeListener(name, l);
|
||||
}
|
||||
|
||||
public void removeVetoableChangeListener(String name,
|
||||
VetoableChangeListener l)
|
||||
{
|
||||
if (l != null)
|
||||
vetoableChangeSupport.removeVetoableChangeListener(name, l);
|
||||
}
|
||||
|
||||
public VetoableChangeListener[] getVetoableChangeListeners(String name)
|
||||
{
|
||||
return vetoableChangeSupport.getVetoableChangeListeners(name);
|
||||
}
|
||||
|
||||
protected void fireVetoableChange(String name, Object o, Object n)
|
||||
throws PropertyVetoException
|
||||
{
|
||||
vetoableChangeSupport.fireVetoableChange(name, o, n);
|
||||
}
|
||||
|
||||
public void addKeyEventDispatcher(KeyEventDispatcher dispatcher)
|
||||
{
|
||||
if (dispatcher != null)
|
||||
keyEventDispatchers.add(dispatcher);
|
||||
}
|
||||
|
||||
public void removeKeyEventDispatcher(KeyEventDispatcher dispatcher)
|
||||
{
|
||||
keyEventDispatchers.remove(dispatcher);
|
||||
}
|
||||
|
||||
protected List getKeyEventDispatchers()
|
||||
{
|
||||
return (List) keyEventDispatchers.clone();
|
||||
}
|
||||
|
||||
public void addKeyEventPostProcessor(KeyEventPostProcessor postProcessor)
|
||||
{
|
||||
if (postProcessor != null)
|
||||
keyEventPostProcessors.add(postProcessor);
|
||||
}
|
||||
|
||||
public void removeKeyEventPostProcessor(KeyEventPostProcessor postProcessor)
|
||||
{
|
||||
keyEventPostProcessors.remove(postProcessor);
|
||||
}
|
||||
|
||||
protected List getKeyEventPostProcessors()
|
||||
{
|
||||
return (List) keyEventPostProcessors.clone();
|
||||
}
|
||||
|
||||
public abstract boolean dispatchEvent(AWTEvent e);
|
||||
|
||||
public final void redispatchEvent(Component target, AWTEvent e)
|
||||
{
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
public abstract boolean dispatchKeyEvent(KeyEvent e);
|
||||
|
||||
public abstract boolean postProcessKeyEvent(KeyEvent e);
|
||||
|
||||
public abstract void processKeyEvent(Component focused, KeyEvent e);
|
||||
|
||||
protected abstract void enqueueKeyEvents(long after, Component untilFocused);
|
||||
|
||||
protected abstract void dequeueKeyEvents(long after, Component untilFocused);
|
||||
|
||||
protected abstract void discardKeyEvents(Component comp);
|
||||
|
||||
public abstract void focusNextComponent(Component comp);
|
||||
|
||||
public abstract void focusPreviousComponent(Component comp);
|
||||
|
||||
public abstract void upFocusCycle(Component comp);
|
||||
|
||||
public abstract void downFocusCycle(Container cont);
|
||||
|
||||
public final void focusNextComponent()
|
||||
{
|
||||
focusNextComponent(focusOwner);
|
||||
}
|
||||
|
||||
public final void focusPreviousComponent()
|
||||
{
|
||||
focusPreviousComponent(focusOwner);
|
||||
}
|
||||
|
||||
public final void upFocusCycle()
|
||||
{
|
||||
upFocusCycle(focusOwner);
|
||||
}
|
||||
|
||||
public final void downFocusCycle()
|
||||
{
|
||||
if (focusOwner instanceof Container
|
||||
&& ((Container) focusOwner).isFocusCycleRoot())
|
||||
downFocusCycle((Container) focusOwner);
|
||||
}
|
||||
} // class KeyboardFocusManager
|
Loading…
Add table
Add a link
Reference in a new issue