-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
6
-
x86
-
windows_xp
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
A JTableHeader that implements TableCellRenderer and is set as its own DefaultRenderer will cause a StackOverFlowError in updateUI().
This is caused by
TableCellRenderer renderer = getDefaultRenderer();
if (!(renderer instanceof UIResource) && renderer instanceof Component) {
SwingUtilities.updateComponentTreeUI((Component)renderer);
}
in JTableHeader.java. updateComponentTreeUI calls updateUI and this leads to infinite recursion in the described situation.
The above code should be changed to
TableCellRenderer renderer = getDefaultRenderer();
if (renderer != this && !(renderer instanceof UIResource) && renderer instanceof Component) {
SwingUtilities.updateComponentTreeUI((Component)renderer);
}
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Write a JTableHeader that implements TableCellRenderer. Create an instance head. Call head.setDefaultRenderer(head). Call updateUI().
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
no error
ACTUAL -
StackOverflowError
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.StackOverflowError
at java.awt.Container.findComponentAtImpl(Container.java:2498)
at java.awt.Container.findComponentAtImpl(Container.java:2528)
at java.awt.Container.findComponentAtImpl(Container.java:2528)
at java.awt.Container.findComponentAtImpl(Container.java:2528)
at java.awt.Container.findComponentAtImpl(Container.java:2528)
at java.awt.Container.findComponentAt(Container.java:2492)
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.BasicTableHeaderUI.uninstallUI(BasicTableHeaderUI.java:333)
at javax.swing.JComponent.setUI(JComponent.java:646)
at javax.swing.table.JTableHeader.setUI(JTableHeader.java:437)
at javax.swing.table.JTableHeader.updateUI(JTableHeader.java:451)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1206)
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1197)
at javax.swing.table.JTableHeader.updateUI(JTableHeader.java:455)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1206)
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1197)
at javax.swing.table.JTableHeader.updateUI(JTableHeader.java:455)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1206)
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1197)
etc.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class StackOverflowHeader extends JTableHeader implements TableCellRenderer {
public StackOverflowHeader() {
setDefaultRenderer(this);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int col) {
return new JLabel(String.valueOf(value));
}
private static class SimpleTableDemo extends JPanel {
public SimpleTableDemo() {
super(new GridLayout(1,0));
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
Object[][] data = {
{"Mary", "Campione",
"Snowboarding", new Integer(5), new Boolean(false)},
{"Alison", "Huml",
"Rowing", new Integer(3), new Boolean(true)},
{"Kathy", "Walrath",
"Knitting", new Integer(2), new Boolean(false)},
{"Sharon", "Zakhour",
"Speed reading", new Integer(20), new Boolean(true)},
{"Philip", "Milne",
"Pool", new Integer(10), new Boolean(false)}
};
final JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
//table.setFillsViewportHeight(true);
table.setTableHeader(new StackOverflowHeader());
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Add the scroll pane to this panel.
add(scrollPane);
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
SwingUtilities.updateComponentTreeUI(frame); //calls StackOverflowHeader.updateUI()
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
override updateUI() as follows
public void updateUI(){
setUI((TableHeaderUI)UIManager.getUI(this));
}
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
A JTableHeader that implements TableCellRenderer and is set as its own DefaultRenderer will cause a StackOverFlowError in updateUI().
This is caused by
TableCellRenderer renderer = getDefaultRenderer();
if (!(renderer instanceof UIResource) && renderer instanceof Component) {
SwingUtilities.updateComponentTreeUI((Component)renderer);
}
in JTableHeader.java. updateComponentTreeUI calls updateUI and this leads to infinite recursion in the described situation.
The above code should be changed to
TableCellRenderer renderer = getDefaultRenderer();
if (renderer != this && !(renderer instanceof UIResource) && renderer instanceof Component) {
SwingUtilities.updateComponentTreeUI((Component)renderer);
}
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Write a JTableHeader that implements TableCellRenderer. Create an instance head. Call head.setDefaultRenderer(head). Call updateUI().
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
no error
ACTUAL -
StackOverflowError
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.StackOverflowError
at java.awt.Container.findComponentAtImpl(Container.java:2498)
at java.awt.Container.findComponentAtImpl(Container.java:2528)
at java.awt.Container.findComponentAtImpl(Container.java:2528)
at java.awt.Container.findComponentAtImpl(Container.java:2528)
at java.awt.Container.findComponentAtImpl(Container.java:2528)
at java.awt.Container.findComponentAt(Container.java:2492)
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.BasicTableHeaderUI.uninstallUI(BasicTableHeaderUI.java:333)
at javax.swing.JComponent.setUI(JComponent.java:646)
at javax.swing.table.JTableHeader.setUI(JTableHeader.java:437)
at javax.swing.table.JTableHeader.updateUI(JTableHeader.java:451)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1206)
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1197)
at javax.swing.table.JTableHeader.updateUI(JTableHeader.java:455)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1206)
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1197)
at javax.swing.table.JTableHeader.updateUI(JTableHeader.java:455)
at javax.swing.SwingUtilities.updateComponentTreeUI0(SwingUtilities.java:1206)
at javax.swing.SwingUtilities.updateComponentTreeUI(SwingUtilities.java:1197)
etc.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class StackOverflowHeader extends JTableHeader implements TableCellRenderer {
public StackOverflowHeader() {
setDefaultRenderer(this);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int col) {
return new JLabel(String.valueOf(value));
}
private static class SimpleTableDemo extends JPanel {
public SimpleTableDemo() {
super(new GridLayout(1,0));
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
Object[][] data = {
{"Mary", "Campione",
"Snowboarding", new Integer(5), new Boolean(false)},
{"Alison", "Huml",
"Rowing", new Integer(3), new Boolean(true)},
{"Kathy", "Walrath",
"Knitting", new Integer(2), new Boolean(false)},
{"Sharon", "Zakhour",
"Speed reading", new Integer(20), new Boolean(true)},
{"Philip", "Milne",
"Pool", new Integer(10), new Boolean(false)}
};
final JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
//table.setFillsViewportHeight(true);
table.setTableHeader(new StackOverflowHeader());
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Add the scroll pane to this panel.
add(scrollPane);
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
SwingUtilities.updateComponentTreeUI(frame); //calls StackOverflowHeader.updateUI()
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
override updateUI() as follows
public void updateUI(){
setUI((TableHeaderUI)UIManager.getUI(this));
}
- duplicates
-
JDK-6567433 JComponent.updateUI() may create StackOverflowError
-
- Resolved
-