Duplicate :
|
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)); }