改变 JTable TableHeaders 背后的背景

Change background behind JTable TableHeaders

我有一个应用程序有几个 tables 和一个白色的应用程序背景以与使用过的徽标融为一体。我已将所有背景设置为白色,但有一个 space 目前我无法达到。
使用我正在使用的标准 JTable,可以移动列,这完全没问题。但是,当移动列时,您仍然可以看到表头后面的标准应用程序颜色。在 JScrollPane 中显示时,我认为设置 ScrollPane.getContentHeader() 的背景会有所帮助,但我得到了 NPE。

下面是一个应该显示问题的小程序:

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

移动三列之一时,您会注意到 LAF 的标准背景(对我来说,它是标准 Windows LAF,其颜色类似于米色)而不是白色,尽管 TableHeader 的背景是设置为白色。
对于没有显示 tableheaders 的 scrollPane 宽度部分也设置了颜色,并将 header 的颜色设置为正确的颜色,但我不知道如何header 后面的 space 这样做。

编辑:在这似乎被误解之后,我对我的问题进行了筛选:

很遗憾,您看不到光标,但我将列固定在 header 处并将其拖到右侧。

你的问题是基于代码行(因为我认为 JTable 没有被指定为 non_resizable,也许这是错误也许是它的功能)

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

您可以覆盖此绘画人工制品,然后在 Renderer

中覆盖所需的 Color
table.getTableHeader().setBackground(scrollPane.getBackground()); 

我会使用 JTable.AUTO_RESIZE_OFF,在大多数情况下没有理由限制为固定大小,我的观点是在所有情况下都使用 LayoutManager,没有任何限制(s ), 例如

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;
//

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

编辑

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

去看

来自代码(再次使用渲染器在 JTables 视图中绘制颜色)

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;
//

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

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

在框架可见之前,table header 并未真正添加到框架中。此时scrollpane会从table中获取table header,并将header添加到scrollpane的header列中。

因此,在框架可见后,您可以执行以下操作:

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

因此,除了按照@mKorbel 的建议设置四个级别之外,还需要以上内容。

您还可以查看:Setting JTableHeader holder background colour 以获得更详细的答案。