I have rewritten MenuSelectionManager.setSelectedPath() to fix
Bug#27326. It seems much more straightforward to me and seems to work
with popup menus and normal menus too.
006-05-02 Roman Kennke <[EMAIL PROTECTED]>
PR 27326
* javax/swing/MenuSelectionManager.java
(setSelectedPath): Rewritten.
/Roman
Index: javax/swing/MenuSelectionManager.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/MenuSelectionManager.java,v
retrieving revision 1.16
diff -u -1 -0 -r1.16 MenuSelectionManager.java
--- javax/swing/MenuSelectionManager.java 8 Apr 2006 16:51:12 -0000 1.16
+++ javax/swing/MenuSelectionManager.java 2 May 2006 12:53:29 -0000
@@ -358,67 +358,49 @@
* @param path new selection path
*/
public void setSelectedPath(MenuElement[] path)
{
if (path == null)
{
clearSelectedPath();
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 ((i + 1) < path.length && path[i + 1].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();
}
/**
* Returns path to the specified component
*
* @param c component for which to find path for
*