Search code examples
javaswingjtablejtableheader

Setting JTableHeader holder background colour


I have a JTable in my program and I wanted to change the color of the JTableHeader. I did this using the following code

JTableHeader header = table.getTableHeader();
header.setBackground(Color.WHITE);

However, when I dragged the header, I noticed that there was a grey area behind the header as shown in the photo below.

enter image description here

How can I set this to white so that it fits in with my JTableHeader?

MCVE

import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class JTableTest extends JFrame {
    private JTableTest()  {
        super("JTable Test");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(1, 1));
        createPanel();
        pack();
        setVisible(true);
    }

    JPanel panel = new JPanel(new GridLayout(1, 1));
    JScrollPane scroll = new JScrollPane();

    private void createPanel() {
        Object[] headers = {"Select", "Title", "Artist", "Length"};
        Object[][] sampleData = {{true, "Bat Outta Hell", "Meat Loaf", "673"},
                {false, "Spanish Train", "Chris De Burgh", "358"}};
        JTable table = new JTable(sampleData, headers);
        ///
        JTableHeader header = table.getTableHeader();
        header.setBackground(Color.WHITE); //Sets header white
        ///
        scroll.getViewport().add(table);
        scroll.getViewport().setBackground(Color.WHITE); //Sets table container white
        panel.add(scroll);
        panel.setBackground(Color.WHITE); //Sets scroll pane container white
        getContentPane().add(panel);
        getContentPane().setBackground(Color.WHITE); //Sets panel container white
        //What should be set to white to make header container white
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater (
            new Runnable() {
                @Override
                public void run() {
                    new JTableTest();
                }
            }
        );
    }
}

Solution

  • Well as I expected we need to set the parent of the header to be the background color you want.

    However the scroll pane is NOT the parent of the header as I expected.

    When I added code like the following:

    System.out.println( header.getParent() );
    

    it showed a JViewport as the parent which confused me.

    However when I added:

    System.out.println( scroll.getViewport() );
    

    I noticed that the two viewports were different. So it appears the viewport of the scrollpane is different than the viewport of the header.

    so the solution to the problem is:

    JTableHeader header = table.getTableHeader();
    header.setBackground(Color.GREEN); 
    

    and then AFTER the frame is visible you can do:

    header.getParent().setBackground(Color.YELLOW);
    

    (I used different colors just to show the effects of each statement)

    Note the header is not added to the scrollpane until the frame is packed or made visible. If you try to set the background when the table is created you will get a NPE when trying to access the parent.

    Or another option is to add an AncestorListener to the JTableHeader. Then the code can be invoked then header is added to a visible frame. For this type of approach check out the Request Focus Listener found in Dialog Focus