[kaffe] CVS kaffe (riccardo): further focus traversal improvments from CP
Kaffe CVS
cvs-commits at kaffe.org
Tue Jul 11 09:03:22 PDT 2006
PatchSet 7333
Date: 2006/07/11 15:39:24
Author: riccardo
Branch: HEAD
Tag: (none)
Log:
further focus traversal improvments from CP
Members:
ChangeLog:1.4836->1.4837
libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.15->1.16
libraries/javalib/awt-implementations/kaffe/java/awt/Container.java:1.7->1.8
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4836 kaffe/ChangeLog:1.4837
--- kaffe/ChangeLog:1.4836 Tue Jul 11 14:33:54 2006
+++ kaffe/ChangeLog Tue Jul 11 15:39:24 2006
@@ -1,3 +1,9 @@
+2006-07-11 Riccardo Mottola <riccardo at kaffe.org>
+
+ * libraries/javalib/awt-implementations/kaffe/java/awt/Component.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/Container.java:
+ further focus traversal improvments from CP
+
2006-07-11 Dalibor Topic <robilad at kaffe.org>
* configure.ac (REGEN_FORWARD): Removed.
Index: kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java
diff -u kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.15 kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.16
--- kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.15 Mon Jul 10 22:51:20 2006
+++ kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Component.java Tue Jul 11 15:39:28 2006
@@ -3446,53 +3446,67 @@
return (getClass().getName() + '[' + paramString() + ']');
}
-/**
- * Transfer the focus to the next appropriate components in this
- * components container.
- */
-public void transferFocus() {
- Component curr = this;
-
- while (curr.parent != null) {
-
- Container parent = curr.parent;
- int end = parent.getComponentCount();
-
- /* Find out where 'curr' is in its container so we can start
- * looking for the next component after it
- */
- int start;
- for (start = 0; start < end; start++) {
- Component c = parent.getComponent(start);
- if (c == curr) {
- break;
- }
- }
-
- /* This shouldn't happen but just in case ... */
- if (start == end) {
- return;
- }
-
- /* Look for next focusable component after me */
- for (start++; start < end; start++) {
- Component c = parent.getComponent(start);
-
- if (c.isEnabled() && ((c.flags & IS_VISIBLE) !=0) && c.isFocusTraversable()) {
- // Then if it is enabled, visible and focus traversable set the focus to it
- c.requestFocus();
- return;
- } else if (c instanceof Container) {
- // If it is a container drop into it
- parent = (Container)c;
- end = parent.getComponentCount();
- start = -1;
- }
- }
-
- curr = parent;
- }
-}
+ /**
+ * Returns the root container that owns the focus cycle where this
+ * component resides. A focus cycle root is in two cycles, one as
+ * the ancestor, and one as the focusable element; this call always
+ * returns the ancestor.
+ *
+ * @return the ancestor container that owns the focus cycle
+ * @since 1.4
+ */
+ public Container getFocusCycleRootAncestor ()
+ {
+ Container parent = getParent ();
+
+ while (parent != null && !parent.isFocusCycleRoot())
+ parent = parent.getParent ();
+
+ return parent;
+ }
+
+ /**
+ * Tests if the container is the ancestor of the focus cycle that
+ * this component belongs to.
+ *
+ * @param c the container to test
+ * @return true if c is the focus cycle root
+ * @since 1.4
+ */
+ public boolean isFocusCycleRoot (Container c)
+ {
+ return c == getFocusCycleRootAncestor ();
+ }
+
+ public void transferFocus ()
+ {
+ // Find the nearest valid (== showing && focusable && enabled) focus
+ // cycle root ancestor and the focused component in it.
+ Container focusRoot = getFocusCycleRootAncestor();
+ Component focusComp = this;
+ while (focusRoot != null
+ && ! (focusRoot.isShowing() && focusRoot.isFocusable()
+ && focusRoot.isEnabled()))
+ {
+ focusComp = focusRoot;
+ focusRoot = focusComp.getFocusCycleRootAncestor();
+ }
+
+ if (focusRoot != null)
+ {
+ // First try to get the componentBefore from the policy.
+ FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
+ Component nextFocus = policy.getComponentAfter(focusRoot, focusComp);
+
+ // If this fails, then ask for the defaultComponent.
+ if (nextFocus == null)
+ nextFocus = policy.getDefaultComponent(focusRoot);
+
+ // Request focus on this component, if not null.
+ if (nextFocus != null)
+ nextFocus.requestFocus();
+ }
+ }
PopupMenu triggerPopup ( int x, int y ) {
if ( popup != null ) {
Index: kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Container.java
diff -u kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Container.java:1.7 kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Container.java:1.8
--- kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Container.java:1.7 Fri May 12 14:38:38 2006
+++ kaffe/libraries/javalib/awt-implementations/kaffe/java/awt/Container.java Tue Jul 11 15:39:28 2006
@@ -17,9 +17,14 @@
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
+import java.awt.event.KeyEvent;
import java.awt.event.PaintEvent;
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
abstract public class Container
@@ -29,15 +34,37 @@
* Compatible with JDK 1.0+.
*/
private static final long serialVersionUID = 4613797578919906343L;
+
/* Serialized fields from the serialization spec. */
int ncomponents;
Component[] component;
LayoutManager layoutMgr;
+ /**
+ * @since 1.4
+ */
+ boolean focusCycleRoot;
+
+
/* Anything else is non-serializable, and should be declared "transient". */
transient ContainerListener containerListener;
+ /** The focus traversal policy that determines how focus is
+ transferred between this Container and its children. */
+ private FocusTraversalPolicy focusTraversalPolicy;
+
+ /**
+ * The focus traversal keys, if not inherited from the parent or default
+ * keyboard manager. These sets will contain only AWTKeyStrokes that
+ * represent press and release events to use as focus control.
+ *
+ * @see #getFocusTraversalKeys(int)
+ * @see #setFocusTraversalKeys(int, Set)
+ * @since 1.4
+ */
+ transient Set[] focusTraversalKeys;
+
// ContainerListener cntrListener;
Insets insets = Insets.noInsets;
@@ -935,6 +962,321 @@
component[i].validate();
}
+
+ /**
+ * Sets the focus traversal keys for a given traversal operation for this
+ * Container.
+ *
+ * @exception IllegalArgumentException If id is not one of
+ * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
+ * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS,
+ * or if keystrokes contains null, or if any Object in keystrokes is not an
+ * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event, or if any
+ * keystroke already maps to another focus traversal operation for this
+ * Container.
+ *
+ * @since 1.4
+ */
+ public void setFocusTraversalKeys(int id, Set keystrokes)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+
+ if (keystrokes == null)
+ {
+ Container parent = getParent ();
+
+ while (parent != null)
+ {
+ if (parent.areFocusTraversalKeysSet (id))
+ {
+ keystrokes = parent.getFocusTraversalKeys (id);
+ break;
+ }
+ parent = parent.getParent ();
+ }
+
+ if (keystrokes == null)
+ keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
+ getDefaultFocusTraversalKeys (id);
+ }
+
+ Set sa;
+ Set sb;
+ Set sc;
+ String name;
+ switch (id)
+ {
+ case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ sc = getFocusTraversalKeys
+ (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+ name = "forwardFocusTraversalKeys";
+ break;
+ case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ sc = getFocusTraversalKeys
+ (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+ name = "backwardFocusTraversalKeys";
+ break;
+ case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ sc = getFocusTraversalKeys
+ (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
+ name = "upCycleFocusTraversalKeys";
+ break;
+ case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
+ sa = getFocusTraversalKeys
+ (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ sb = getFocusTraversalKeys
+ (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ sc = getFocusTraversalKeys
+ (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
+ name = "downCycleFocusTraversalKeys";
+ 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 ();
+ }
+
+ if (focusTraversalKeys == null)
+ focusTraversalKeys = new Set[4];
+
+ keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
+ firePropertyChange (name, focusTraversalKeys[id], keystrokes);
+
+ focusTraversalKeys[id] = keystrokes;
+ }
+
+ /**
+ * Returns the Set of focus traversal keys for a given traversal operation for
+ * this Container.
+ *
+ * @exception IllegalArgumentException If id is not one of
+ * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
+ * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS.
+ *
+ * @since 1.4
+ */
+ public Set getFocusTraversalKeys (int id)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+
+ Set s = null;
+
+ if (focusTraversalKeys != null)
+ s = focusTraversalKeys[id];
+
+ if (s == null && parent != null)
+ s = parent.getFocusTraversalKeys (id);
+
+ return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
+ .getDefaultFocusTraversalKeys(id)) : s;
+ }
+
+ /**
+ * Returns whether the Set of focus traversal keys for the given focus
+ * traversal operation has been explicitly defined for this Container.
+ * If this method returns false, this Container is inheriting the Set from
+ * an ancestor, or from the current KeyboardFocusManager.
+ *
+ * @exception IllegalArgumentException If id is not one of
+ * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
+ * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS,
+ * or KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS.
+ *
+ * @since 1.4
+ */
+ public boolean areFocusTraversalKeysSet (int id)
+ {
+ if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS &&
+ id != KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS)
+ throw new IllegalArgumentException ();
+
+ return focusTraversalKeys != null && focusTraversalKeys[id] != null;
+ }
+
+ /**
+ * Check whether the given Container is the focus cycle root of this
+ * Container's focus traversal cycle. If this Container is a focus
+ * cycle root itself, then it will be in two different focus cycles
+ * -- it's own, and that of its ancestor focus cycle root's. In
+ * that case, if <code>c</code> is either of those containers, this
+ * method will return true.
+ *
+ * @param c the candidate Container
+ *
+ * @return true if c is the focus cycle root of the focus traversal
+ * cycle to which this Container belongs, false otherwise
+ *
+ * @since 1.4
+ */
+ public boolean isFocusCycleRoot (Container c)
+ {
+ if (this == c
+ && isFocusCycleRoot ())
+ return true;
+
+ Container ancestor = getFocusCycleRootAncestor ();
+
+ if (c == ancestor)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * If this Container is a focus cycle root, set the focus traversal
+ * policy that determines the focus traversal order for its
+ * children. If non-null, this policy will be inherited by all
+ * inferior focus cycle roots. If <code>policy</code> is null, this
+ * Container will inherit its policy from the closest ancestor focus
+ * cycle root that's had its policy set.
+ *
+ * @param policy the new focus traversal policy for this Container or null
+ *
+ * @since 1.4
+ */
+ public void setFocusTraversalPolicy (FocusTraversalPolicy policy)
+ {
+ focusTraversalPolicy = policy;
+ }
+
+ /**
+ * Return the focus traversal policy that determines the focus
+ * traversal order for this Container's children. This method
+ * returns null if this Container is not a focus cycle root. If the
+ * focus traversal policy has not been set explicitly, then this
+ * method will return an ancestor focus cycle root's policy instead.
+ *
+ * @return this Container's focus traversal policy or null
+ *
+ * @since 1.4
+ */
+ public FocusTraversalPolicy getFocusTraversalPolicy ()
+ {
+ if (!isFocusCycleRoot ())
+ return null;
+
+ if (focusTraversalPolicy == null)
+ {
+ Container ancestor = getFocusCycleRootAncestor ();
+
+ if (ancestor != this && ancestor != null)
+ return ancestor.getFocusTraversalPolicy ();
+ else
+ {
+ KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
+
+ return manager.getDefaultFocusTraversalPolicy ();
+ }
+ }
+ else
+ return focusTraversalPolicy;
+ }
+
+ /**
+ * Check whether this Container's focus traversal policy has been
+ * explicitly set. If it has not, then this Container will inherit
+ * its focus traversal policy from one of its ancestor focus cycle
+ * roots.
+ *
+ * @return true if focus traversal policy is set, false otherwise
+ */
+ public boolean isFocusTraversalPolicySet ()
+ {
+ return focusTraversalPolicy == null;
+ }
+
+ /**
+ * Set whether or not this Container is the root of a focus
+ * traversal cycle. This Container's focus traversal policy
+ * determines the order of focus traversal. Some policies prevent
+ * the focus from being transferred between two traversal cycles
+ * until an up or down traversal operation is performed. In that
+ * case, normal traversal (not up or down) is limited to this
+ * Container and all of this Container's descendents that are not
+ * descendents of inferior focus cycle roots. In the default case
+ * however, ContainerOrderFocusTraversalPolicy is in effect, and it
+ * supports implicit down-cycle traversal operations.
+ *
+ * @param focusCycleRoot true if this is a focus cycle root, false otherwise
+ *
+ * @since 1.4
+ */
+ public void setFocusCycleRoot (boolean focusCycleRoot)
+ {
+ this.focusCycleRoot = focusCycleRoot;
+ }
+
+ /**
+ * Check whether this Container is a focus cycle root.
+ *
+ * @return true if this is a focus cycle root, false otherwise
+ *
+ * @since 1.4
+ */
+ public boolean isFocusCycleRoot ()
+ {
+ return focusCycleRoot;
+ }
+
+ /**
+ * Transfer focus down one focus traversal cycle. If this Container
+ * is a focus cycle root, then its default component becomes the
+ * focus owner, and this Container becomes the current focus cycle
+ * root. No traversal will occur if this Container is not a focus
+ * cycle root.
+ *
+ * @since 1.4
+ */
+ public void transferFocusDownCycle ()
+ {
+ if (isFocusCycleRoot())
+ {
+ KeyboardFocusManager fm =
+ KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ fm.setGlobalCurrentFocusCycleRoot(this);
+ FocusTraversalPolicy policy = getFocusTraversalPolicy();
+ Component defaultComponent = policy.getDefaultComponent(this);
+ if (defaultComponent != null)
+ defaultComponent.requestFocus();
+ }
+ }
/**
More information about the kaffe
mailing list