geisterfurz007
geisterfurz007

Reputation: 5874

Change background behind JTable TableHeaders

I have an application with a few tables and a white application background to blend in with used logos. I have set all the backgrounds to white but there is one space that I could not reach so far.
With the standard JTable I am using it is possible to move columns and this is totally fine. However when moving the columns you are still able to see the standard applications color behind the TableHeaders. As displaying in a JScrollPane I thought setting the background of the ScrollPane.getContentHeader() would help but I get an NPE.

Below is a small program that should display the problem:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class testsforSO extends JFrame {

    private static final long serialVersionUID = -3890178393751567629L;
    private JTable table;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    testsforSO frame = new testsforSO();
                    frame.setSize(300, 300);
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public testsforSO() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout(0, 0));

        JScrollPane scrollPane = new JScrollPane();
        getContentPane().add(scrollPane, BorderLayout.CENTER);



        String[] columns = new String[] { "ABC", "DEF", "XYZ" };
        TableModel tm = new DefaultTableModel(columns, 3);

        table = new JTable();
        table.setModel(tm);
        table.getTableHeader().setBackground(Color.WHITE); //Does its job
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        scrollPane.setViewportView(table);
    }
}

When moving one of the three columns you will notice the standard background of your LAF (for me it is the Standard Windows LAF with its beige like color) instead of white eventhough the background of the TableHeader is set to white.
The color is set as well for the parts of the scrollPane width where no tableheaders are displayed and sets the color of the header to the correct color but I cannot figure out how to do so for the space behind the headers.

EDIT: After this seems to get misunderstood, I made a screen of my problem:

Unfortunately you cannot see the cursor, but I am holding the column at its header and dragging it to the right.

Upvotes: 1

Views: 796

Answers (2)

camickr
camickr

Reputation: 324098

none of them worked, where the last one brings up an NPE.

The table header is not actually added to the frame until the frame is visible. At this time the scrollpane will get the table header from the table and add the header to the column header of the scrollpane.

So, AFTER the frame is visible you can do:

JTableHeader header = table.getTableHeader();
header.getParent().setBackground(Color.YELLOW);

So the above is required in addition to setting the four levels as suggested by @mKorbel.

You can also check out: Setting JTableHeader holder background colour for a more detailed answer.

Upvotes: 2

mKorbel
mKorbel

Reputation: 109815

your problem are based on code line (because I think that JTable aren't designated to be non_resizable, maybe this is bug maybe its feature)

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

you can to override this painting artefact by, then override the desired Color in Renderer

table.getTableHeader().setBackground(scrollPane.getBackground()); 

I'd be use JTable.AUTO_RESIZE_OFF, in most case there isn't reason to be restricted to fixed size, my view is to use LayoutManager in all cases, without any restriction(s), e.g.

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
//http://stackoverflow.com/questions/40969405/change-background-behind-jtable-tableheaders

public class testsforSO extends JFrame {

    private static final long serialVersionUID = -3890178393751567629L;
    private JScrollPane scrollPane = new JScrollPane();
    private String[] columns = new String[]{"ABC", "DEF", "XYZ"};
    private TableModel tm = new DefaultTableModel(columns, 3);
    private JTable table = new JTable(tm);

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    testsforSO frame = new testsforSO();
                    frame.pack();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public testsforSO() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JScrollPane scrollPane = new JScrollPane();
        String[] columns = new String[]{"ABC", "DEF", "XYZ"};
        TableModel tm = new DefaultTableModel(columns, 3);
        table.getTableHeader().setBackground(Color.WHITE); //Does its job
        table.getTableHeader().setBackground(scrollPane.getBackground());
        table.getTableHeader().setOpaque(true);
        table.setFillsViewportHeight(true);
        //table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setPreferredScrollableViewportSize(new Dimension(300, 100));
        scrollPane.setViewportView(table);
        add(scrollPane);
    }
}

EDIT

Try your program you gave as an answer (including scrollPane.getViewport().setBackground(Color.BLACK);) and run it. Black shows the problem better.

to see

enter image description here

from code (again to use Renderer for painting the Color inside JTables view)

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
//http://stackoverflow.com/questions/40969405/change-background-behind-jtable-tableheaders

public class testsforSO extends JFrame {

    private static final long serialVersionUID = -3890178393751567629L;
    private JScrollPane scrollPane = new JScrollPane();
    private String[] columns = new String[]{"ABC", "DEF", "XYZ"};
    private TableModel tm = new DefaultTableModel(columns, 3);
    private JTable table = new JTable(tm);

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    testsforSO frame = new testsforSO();
                    frame.pack();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public testsforSO() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JScrollPane scrollPane = new JScrollPane();
        String[] columns = new String[]{"ABC", "DEF", "XYZ"};
        TableModel tm = new DefaultTableModel(columns, 3);
        //table.getTableHeader().setBackground(Color.WHITE); //Does its job
        table.getTableHeader().setBackground(Color.BLACK);
        table.setFillsViewportHeight(true);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setBackground(Color.BLACK);
        table.setPreferredScrollableViewportSize(new Dimension(300, 100));
        scrollPane.getViewport().setBackground(Color.BLACK);
        scrollPane.setViewportView(table);
        add(scrollPane);
    }
}

Upvotes: 5

Related Questions