-
Bug
-
Resolution: Fixed
-
P4
-
6, 7, 8, 9
-
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.
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.
- duplicates
-
JDK-6625661 updateUI causes StackOverflowError in JTableHeaders that are their own renderers
-
- Closed
-
- relates to
-
JDK-6364555 Some SwingSet2 components do not dynamically update font antialiasing.
-
- Resolved
-