diff options
| author | Eric Blake <ebb9@byu.net> | 2002-05-06 02:43:17 +0000 |
|---|---|---|
| committer | Eric Blake <ebb9@byu.net> | 2002-05-06 02:43:17 +0000 |
| commit | fb0219dcce2e53020800c655562b5f7351b0579b (patch) | |
| tree | 9f82123162f4b28fe313e1777997035fb852cabf /java/awt/KeyboardFocusManager.java | |
| parent | d76bb31a7c2246eea1f5f1b9624b8ddf1d841b88 (diff) | |
| download | classpath-fb0219dcce2e53020800c655562b5f7351b0579b.tar.gz | |
2002-05-05 Eric Blake <ebb9@email.byu.edu>
* java/applet/Applet.java (getAccessibleState): Update.
* java/awt/AWTEvent.java (INPUT_ENABLED_EVENT_MASK): New flag.
* java/awt/AWTKeyStroke.java (keyCode): Make more visible.
* java/awt/AlphaComposite.java: New file (needs documentation).
* java/awt/AttributeValue.java: New file.
* java/awt/BasicStroke.java: New file (needs docs).
* java/awt/BufferCapabilities.java: New file (needs docs).
* java/awt/Button.java (getActionListeners, getListeners): Use new
features of AWTEventMulticater.
* java/awt/Component.java: Partial update to 1.4.
* java/awt/ComponentOrientation.java: Update to 1.4.
* java/awt/Container.java (getContainerListeners, getListeners):
Use new features of AWTEventMulticaster.
* java/awt/ContainerOrderFocusTraversalPolicy.java: New
file (stubbed, needs docs).
* java/awt/DefaultFocusTraversalPolicy.java: New file (stubbed).
* java/awt/DefaultKeyboardFocusManager.java: New file (stubbed).
* java/awt/FocusTraversalPolicy.java: New file (needs docs).
* java/awt/GradientPaint.java: New file (stubbed).
* java/awt/GraphicsConfiguration.java: Update to 1.4.
* java/awt/ImageCapabilities.java: New file (stubbed).
* java/awt/Insets.java: Update to 1.4.
* java/awt/JobAttributes.java: New file (needs docs).
* java/awt/KeyboardFocusManager.java: New file (partially
stubbed).
* java/awt/Makefile.am (EXTRA_DIST): Account for new files.
* java/awt/MenuItem.java (getActionListeners, getListeners): Use
new features of AWTEventMulticaster.
* java/awt/PageAttributes.java: New file (needs docs).
* java/awt/PaintContext.java (paint): Remove redundant keyword.
* java/awt/PrintJob.java: Update to 1.4.
* java/awt/RenderingHints.java: Partial update to 1.4 (needs docs).
* java/awt/Robot.java: New file (stubbed).
* java/awt/TexturePaint.java: New file (stubbed).
* java/awt/Window.java (getWindowListeners, getListeners): Use new
features of AWTEventMulticaster.
* java/awt/geom/Arc2D.java: Implement and document.
* java/awt/geom/Rectangle2D.java: Fix doc typo.
Diffstat (limited to 'java/awt/KeyboardFocusManager.java')
| -rw-r--r-- | java/awt/KeyboardFocusManager.java | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/java/awt/KeyboardFocusManager.java b/java/awt/KeyboardFocusManager.java new file mode 100644 index 000000000..2bb17a823 --- /dev/null +++ b/java/awt/KeyboardFocusManager.java @@ -0,0 +1,555 @@ +/* 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 && focusOwner.isFocusCycleRoot()) + downFocusCycle((Container) focusOwner); + } +} // class KeyboardFocusManager |
