summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/MenuSelectionManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/MenuSelectionManager.java')
-rw-r--r--libjava/classpath/javax/swing/MenuSelectionManager.java146
1 files changed, 95 insertions, 51 deletions
diff --git a/libjava/classpath/javax/swing/MenuSelectionManager.java b/libjava/classpath/javax/swing/MenuSelectionManager.java
index 4e52751065a..df7b42037db 100644
--- a/libjava/classpath/javax/swing/MenuSelectionManager.java
+++ b/libjava/classpath/javax/swing/MenuSelectionManager.java
@@ -216,28 +216,90 @@ public class MenuSelectionManager
public boolean isComponentPartOfCurrentMenu(Component c)
{
MenuElement[] subElements;
- for (int i = 0; i < selectedPath.size(); i++)
+ boolean ret = false;
+ for (int i = 0; i < selectedPath.size(); i++)
{
- subElements = ((MenuElement) selectedPath.get(i)).getSubElements();
- for (int j = 0; j < subElements.length; j++)
- {
- MenuElement me = subElements[j];
- if (me != null && (me.getComponent()).equals(c))
- return true;
- }
+ // Check first element.
+ MenuElement first = (MenuElement) selectedPath.get(i);
+ if (SwingUtilities.isDescendingFrom(c, first.getComponent()))
+ {
+ ret = true;
+ break;
+ }
+ else
+ {
+ // Check sub elements.
+ subElements = first.getSubElements();
+ for (int j = 0; j < subElements.length; j++)
+ {
+ MenuElement me = subElements[j];
+ if (me != null
+ && (SwingUtilities.isDescendingFrom(c, me.getComponent())))
+ {
+ ret = true;
+ break;
+ }
+ }
+ }
}
- return false;
+ return ret;
}
/**
- * DOCUMENT ME!
+ * Processes key events on behalf of the MenuElements. MenuElement
+ * instances should always forward their key events to this method and
+ * get their {@link MenuElement#processKeyEvent(KeyEvent, MenuElement[],
+ * MenuSelectionManager)} eventually called back.
*
- * @param e DOCUMENT ME!
+ * @param e the key event
*/
public void processKeyEvent(KeyEvent e)
{
- throw new UnsupportedOperationException("not implemented");
+ MenuElement[] selection = (MenuElement[])
+ selectedPath.toArray(new MenuElement[selectedPath.size()]);
+ MenuElement[] path;
+ for (int index = selection.length - 1; index >= 0; index--)
+ {
+ MenuElement el = selection[index];
+ // This method's main purpose is to forward key events to the
+ // relevant menu items, so that they can act in response to their
+ // mnemonics beeing typed. So we also need to forward the key event
+ // to all the subelements of the currently selected menu elements
+ // in the path.
+ MenuElement[] subEls = el.getSubElements();
+ path = null;
+ for (int subIndex = 0; subIndex < subEls.length; subIndex++)
+ {
+ MenuElement sub = subEls[subIndex];
+ // Skip elements that are not showing or not enabled.
+ if (sub == null || ! sub.getComponent().isShowing()
+ || ! sub.getComponent().isEnabled())
+ {
+ continue;
+ }
+
+ if (path == null)
+ {
+ path = new MenuElement[index + 2];
+ System.arraycopy(selection, 0, path, 0, index + 1);
+ }
+ path[index + 1] = sub;
+ sub.processKeyEvent(e, path, this);
+ if (e.isConsumed())
+ break;
+ }
+ if (e.isConsumed())
+ break;
+ }
+
+ // Dispatch to first element in selection if it hasn't been consumed.
+ if (! e.isConsumed())
+ {
+ path = new MenuElement[1];
+ path[0] = selection[0];
+ path[0].processKeyEvent(e, path, this);
+ }
}
/**
@@ -303,53 +365,35 @@ public class MenuSelectionManager
return;
}
- int i;
- int minSize = path.length; // size of the smaller path.
+ int minSize = path.length; // size of the smaller path.
+ int currentSize = selectedPath.size();
+ int firstDiff = 0;
- if (path.length > selectedPath.size())
+ // Search first item that is different in the current and new path.
+ for (int i = 0; i < minSize; i++)
{
- minSize = selectedPath.size();
-
- // if new selected path contains more elements then current
- // selection then first add all elements at
- // the indexes > selectedPath.size
- for (i = selectedPath.size(); i < path.length; i++)
- {
- selectedPath.add(path[i]);
- path[i].menuSelectionChanged(true);
- }
+ if (i < currentSize && (MenuElement) selectedPath.get(i) == path[i])
+ firstDiff++;
+ else
+ break;
}
- else if (path.length < selectedPath.size())
+ // Remove items from selection and send notification.
+ for (int i = currentSize - 1; i >= firstDiff; i--)
{
- // if new selected path contains less elements then current
- // selection then first remove all elements from the selection
- // at the indexes > path.length
- for (i = selectedPath.size() - 1; i >= path.length; i--)
- {
- ((MenuElement) selectedPath.get(i)).menuSelectionChanged(false);
- selectedPath.remove(i);
- }
-
- minSize = path.length;
+ MenuElement el = (MenuElement) selectedPath.get(i);
+ selectedPath.remove(i);
+ el.menuSelectionChanged(false);
}
- // Now compare elements in new and current selection path at the
- // same location and adjust selection until
- // same menu elements will be encountered at the
- // same index in both current and new selection path.
- MenuElement oldSelectedItem;
-
- for (i = minSize - 1; i >= 0; i--)
+ // Add new items to selection and send notification.
+ for (int i = firstDiff; i < minSize; i++)
{
- oldSelectedItem = (MenuElement) selectedPath.get(i);
-
- if (path[i].equals(oldSelectedItem))
- break;
-
- oldSelectedItem.menuSelectionChanged(false);
- path[i].menuSelectionChanged(true);
- selectedPath.setElementAt(path[i], i);
+ if (path[i] != null)
+ {
+ selectedPath.add(path[i]);
+ path[i].menuSelectionChanged(true);
+ }
}
fireStateChanged();