Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6567433

JComponent.updateUI() may create StackOverflowError

XMLWordPrintable

    • b130
    • x86
    • windows_xp

      FULL PRODUCT VERSION :
      java version "1.6.0_01"
      Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
      Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]


      A DESCRIPTION OF THE PROBLEM :
      Calling updateUI() on several JComponents creates StackOverflowErrors.
      JList.updateUI() for instance invokes updateUI() on his cellrenderer via SwingUtilities.updateComponentTreeUI().
      If the cellrenderer is a parent of this JList the method recurses endless.

      1.6 code:
      public void updateUI() {
      setUI((ListUI)UIManager.getUI(this));

      ListCellRenderer renderer = getCellRenderer();
      if (!(renderer instanceof UIResource) && renderer instanceof Component) {
      SwingUtilities.updateComponentTreeUI((Component)renderer);
      }
      }

      1.6 code:
      public void updateUI() {
      setUI((ListUI)UIManager.getUI(this));
      invalidate();
      }

      The updateUI()-method should flag if it's currently performing the SwingUtilities.updateComponentTreeUI().
      If so then do nothing, e.g.:
      private boolean updatingUI = false;
      public void updateUI() {
      if (updatingUI) return;
      updatingUI = true;
      setUI((ListUI)UIManager.getUI(this));

      ListCellRenderer renderer = getCellRenderer();
      if (!(renderer instanceof UIResource) && renderer instanceof Component) {
      SwingUtilities.updateComponentTreeUI((Component)renderer);
      }
      updatingUI = false;
      }

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      See test case.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      StackOverflowError should not occur.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
      at sun.awt.windows.WGlobalCursorManager.findComponentAt(Native Method)
      at sun.awt.GlobalCursorManager._updateCursor(GlobalCursorManager.java:180)
      at sun.awt.GlobalCursorManager.updateCursorImmediately(GlobalCursorManager.java:82)
      at sun.awt.windows.WComponentPeer.updateCursorImmediately(WComponentPeer.java:538)
      at java.awt.Component.updateCursorImmediately(Component.java:2762)
      at java.awt.Container.remove(Container.java:1170)
      at java.awt.Container.remove(Container.java:1203)
      at javax.swing.plaf.basic.BasicListUI.uninstallUI(BasicListUI.java:883)
      at javax.swing.JComponent.setUI(JComponent.java:646)
      at javax.swing.JList.setUI(JList.java:493)
      at javax.swing.JList.updateUI(JList.java:508)
      at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1206)
      at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1221)
      at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1221)
      at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1221)
      at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1221)
      at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1221)
      at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1221)
      at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1197)
      at javax.swing.JList.updateUI(JList.java:512)
      ...

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;
      import java.awt.*;
      import java.awt.event.ActionListener;
      import java.awt.event.ActionEvent;

      /**
       * Calling updateUI() on several JComponents creates StackOverflowErrors.</p>
       * JList.updateUI() for instance invokes updateUI() on his cellrenderer via
       * SwingUtilities.updateComponentTreeUI().</p>
       * If the cellrenderer is a parent of this JList the method recurses endless.</p>
       *
       * @author FRMEYER
       * @version 06.06.2007 12:46:53
       */
      public class UpdateUITest extends JFrame implements ActionListener, ListCellRenderer {

      JList list;
      DefaultListCellRenderer renderer;

      public UpdateUITest() throws HeadlessException {
      super("UpdateUITest");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setSize(400, 400);

      String[] listData = new String['Z' - 'A' + 1];
      for (int i = 0; i < listData.length; i++) {
      String s = String.valueOf(((char) ('A' + i)));
      while (s.length() < 10) {
      s = s + s;
      }
      listData[i] = s;
      }
      list = new JList(listData);
      list.setCellRenderer(this);
      renderer = new DefaultListCellRenderer();
      getContentPane().add(new JScrollPane(list), BorderLayout.CENTER);

      JButton button = new JButton("crash");
      button.addActionListener(this);
      getContentPane().add(button, BorderLayout.SOUTH);
      }

      public static void main(String[] args) {
      new UpdateUITest().setVisible(true);
      }

      public void actionPerformed(ActionEvent e) {
      list.updateUI();
      }

      public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
      return renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
        To avoid this temporarily replace the JList's cellrenderer with null:
      ListCellRenderer renderer = list.getCellRenderer();
      list.setCellRenderer(null);
      list.updateUI();
      list.setCellRenderer(renderer);
      Needs specific code for other JComponents like JTable, JTree and so on.

            aghaisas Ajit Ghaisas
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: