This patch fixes the SwingUtilities: 1. updateComponentTreeUI has been rewritten. It now handles menus and AWT components in a more correct and robust way. Also, it changes the order in which the components are updated. Before, we went down to the bottommost components in the tree, updated these and when returning back up, update the parents. It should actually be done the other way around. First update the upper components and then dive down and update the children. 2. the replaceXXXMap methods could create loops when the same XXXMap was requested to be replaced (it would register itself as its own parent). This prevented the change-theme feature in the SwingSet demo from working correctly.
2006-03-13 Roman Kennke <[EMAIL PROTECTED]> * javax/swing/SwingUtilities.java (updateComponentTreeUI): Rewritten to be more robust. Handling of menus and non-Swing components is improved. (updateComponentTreeUIImpl): New helper method. (replaceUIActionMap): Added check for uiActionMap==parent to avoid loop. (replaceUIInputMap): Added check for uiInputMap==parent to avoid loop. /Roman
Index: javax/swing/SwingUtilities.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/SwingUtilities.java,v retrieving revision 1.46 diff -u -r1.46 SwingUtilities.java --- javax/swing/SwingUtilities.java 28 Feb 2006 15:15:52 -0000 1.46 +++ javax/swing/SwingUtilities.java 13 Mar 2006 20:35:02 -0000 @@ -600,20 +600,46 @@ */ public static void updateComponentTreeUI(Component comp) { - if (comp == null) - return; - - if (comp instanceof Container) + updateComponentTreeUIImpl(comp); + if (comp instanceof JComponent) { - Component[] children = ((Container)comp).getComponents(); - for (int i = 0; i < children.length; ++i) - updateComponentTreeUI(children[i]); + JComponent jc = (JComponent) comp; + jc.revalidate(); } - - if (comp instanceof JComponent) - ((JComponent)comp).updateUI(); + else + { + comp.invalidate(); + comp.validate(); + } + comp.repaint(); } + /** + * Performs the actual work for [EMAIL PROTECTED] #updateComponentTreeUI(Component)}. + * This calls updateUI() on c if it is a JComponent, and then walks down + * the component tree and calls this method on each child component. + * + * @param c the component to update the UI + */ + private static void updateComponentTreeUIImpl(Component c) + { + if (c instanceof JComponent) + { + JComponent jc = (JComponent) c; + jc.updateUI(); + } + + Component[] components = null; + if (c instanceof JMenu) + components = ((JMenu) c).getMenuComponents(); + else if (c instanceof Container) + components = ((Container) c).getComponents(); + if (components != null) + { + for (int i = 0; i < components.length; ++i) + updateComponentTreeUIImpl(components[i]); + } + } /** * <p>Layout a "compound label" consisting of a text string and an icon @@ -1128,7 +1154,9 @@ child = parent; parent = child.getParent(); } - child.setParent(uiActionMap); + // Sanity check to avoid loops. + if (child != uiActionMap) + child.setParent(uiActionMap); } } @@ -1170,7 +1198,9 @@ child = parent; parent = parent.getParent(); } - child.setParent(uiInputMap); + // Sanity check to avoid loops. + if (child != uiInputMap) + child.setParent(uiInputMap); } }