JDK-6516888 : Wrong LAF for custom table headers when switching to Windows XP LAF
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-01-24
  • Updated: 2011-02-16
  • Resolved: 2007-01-26
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b104)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b104, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Windows XP Professional

A DESCRIPTION OF THE PROBLEM :
If a custom table header is used the look and feel for it is incorrect when Windows LAF is switched to on a Windows XP platform as it uses the Classic theme instead of the XP theme.  It doesn't matter how simple the custom table header is and it also doesn't work even if the header is recreated after switching to Windows LAF.  Note however that the table header renders correctly if Windows LAF is chosen before the table is created.

Please also note that this problem appears to happen when switching to the GTK look and feel as well.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the example using JDK 6.0 on a Windows XP machine.
2. Click on the "Switch PLAF" button.
3. The PLAF is switched to Windows PLAF.  Notice how the top table has a classic Windows look whereas the lower table has a proper XP look.  The only difference between the two is that the top table uses a custom table header.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Custom table headers would be rendered in Windows XP style.
The expected behaviour is that both tables would have an XP look.  
ACTUAL -
Custom table headers rendered in Windows Classic style.
The actual behaviour is that the top table using a custom table header takes on a classic Windows look instead.

---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;

public class Incident860693 extends JFrame
{
	private JButton button;
	private JTable table1, table2;
	private JScrollPane pane1, pane2;
	private JPanel panel;

	private class HeaderRenderer implements TableCellRenderer
	{
		private TableCellRenderer tableCellRenderer;

		public HeaderRenderer(TableCellRenderer tableCellRenderer)
		{
			this.tableCellRenderer = tableCellRenderer;
		}

		public Component getTableCellRendererComponent(JTable table, Object value,
		  boolean isSelected, boolean hasFocus,int row, int column)
		{
			Component c = tableCellRenderer.getTableCellRendererComponent(table, 
			  value, isSelected, hasFocus, row, column);
			return c;
		}
	}

	class MyHeader extends JTableHeader
	{
		public MyHeader(TableColumnModel model)
		{
			super(model);
			setDefaultRenderer(new HeaderRenderer(getDefaultRenderer()));
		}
	}

	/**
	 * Create a new instance of <code>Incident860693</code>.
	 */
	public Incident860693()
	{
		Object[][] data = new Object[][] {{1, 2, 3, 4, 5, 6},
				                          {2, 4, 8, 9, 5, 7},
		                                  {3, 1, 6, 5, 3, 2},
		                                  {4, 6, 6, 7, 6, 8}};
		String[] colNames = new String[] {"A", "B", "C", "D", "E", "F"};
		setLayout(new BorderLayout());
		button = new JButton("Switch PLAF");
		button.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent ae)
			{
				try
				{
					UIManager.setLookAndFeel(new WindowsLookAndFeel());
				}
				catch (UnsupportedLookAndFeelException ulafe)
				{
				}
				SwingUtilities.updateComponentTreeUI(Incident860693.this);
			}
		});
		add(button, BorderLayout.SOUTH);
		pane1 = new JScrollPane();
		pane2 = new JScrollPane();
		table1 = new JTable(data, colNames);
		table2 = new JTable(data, colNames);
		table1.setTableHeader(new MyHeader(table1.getColumnModel()));
		pane1.setViewportView(table1);
		pane2.setViewportView(table2);
		panel = new JPanel(new GridLayout(2, 1));
		panel.add(pane1);
		panel.add(pane2);
		add(panel, BorderLayout.CENTER);
		pack();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setPreferredSize(new Dimension(200, 100));
		setSize(new Dimension(300, 300));
	}

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
		{
			public void run()
			{
				new Incident860693().setVisible(true);
			}
		});
	}
}
---------- END SOURCE ---------------


REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
Maybe by hanging on to the table model and recreating the entire table.

Comments
EVALUATION While this doesn't result in the same symptoms, this is the same issue as 6429812. In particular, the developer can get into trouble when wrapping the default renderer as that renderer is tied to a particular look and feel. I'm closing as a duplicate of 6429812. Any solution, or non-solution, of that bug will be what's needed to solve this issue. As a work-around, the submitter can do the following when it's time to change the look and feel: table.setDefaultRenderer(null); // change look and feel table.setDefaultRenderer(new HeaderRenderer(getDefaultRenderer()));
26-01-2007