JTable AutoCreateRowSorter 导致 Swing 绘制 table 错误

JTable AutoCreateRowSorter causes Swing to Paint the table wrong

我在 java 中创建了一个 JTable,并使用 AutoCreateRowSorter 方法帮助对 table 的列进行排序。

问题是当我单击 header 列对 table 进行排序时,它重新绘制了 table 错误。显示的第一张图片是打开时的外观。第二张图片显示了我单击一次时发生的情况。请注意数据与 headers.

列重叠

Initial JTable

Repainted JTable

public class DataTable {
    String[] colNames = {"Aircraft",
             "Track ID",
             "Runway",
             "Operation Type",
             "Number Daily of Operations"};

    public DataTable(){}

    public static void main(String[] args) {
        DataTable tble = new DataTable();
        JFrame window = new JFrame();
        window.setBounds(0, 10, 1000,700);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.getContentPane().setLayout(new BorderLayout(0, 0));
        window.setContentPane(tble.getfinalPane());
        window.setVisible(true);
    }

    public JPanel getfinalPane(){
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        GridBagConstraints b = new GridBagConstraints();
        b.gridx = 0;
        b.gridy = 0;
        b.fill = GridBagConstraints.BOTH;
        b.anchor = GridBagConstraints.FIRST_LINE_END;
        b.weighty = 500;
        panel.add(getTable(),b);

        return panel;
    }

    public JScrollPane getTable(){
        Object[][] data = {{"Boeing 717",(long) 2459,"01L","Arrival",0.13},{"Boeing 727",(long) 2439,"01R","Arrival",0.12}};
        JTable table = new JTable(data,colNames);
        table.setFont(new Font("Serif",Font.BOLD,20));
        table.getTableHeader().setFont(new Font("Serif",Font.BOLD,20));
        table.getTableHeader().setBackground(new Color(0,0,0,100));
        table.getTableHeader().setBorder(BorderFactory.createMatteBorder(3, 3, 3, 3, Color.BLACK));
        table.getTableHeader().setForeground(Color.WHITE);
        table.setRowHeight(table.getRowHeight()+table.getFont().getSize());
        table.setBackground(new Color(214, 217, 223));
        table.setAutoCreateRowSorter(true);
        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
        centerRenderer.setHorizontalAlignment(SwingConstants.CENTER);

        for(int i = 0; i < colNames.length; i++){
            table.getColumnModel().getColumn(i).setCellRenderer(centerRenderer);
        }

        JScrollPane scroll = new JScrollPane(table);
        scroll.setBackground(new Color(0,0,0,100));
        table.setFillsViewportHeight(true);

        return scroll;
    }

}

我想知道如何解决这个问题。感谢您的帮助。

Swing 不知道如何将基于 alpha 的颜色作为背景色处理,它被设计为仅适用于完全透明或完全不透明的组件。

你可以伪造它,通过扩展组件,使它们透明,然后自己执行填充操作

半透明JScrollPane

public class TranslucentScrollPane extends JScrollPane {

    public TranslucentScrollPane() {
        setOpaque(false);
        getViewport().setOpaque(false);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(getBackground());
        g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
        super.paintComponent(g2d);
        g2d.dispose();
    }

}

半透明JTableHeader

public class TranslucentTableHeader extends JTableHeader {

    public TranslucentTableHeader() {
        setOpaque(false);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(getBackground());
        g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
        super.paintComponent(g2d);
        g2d.dispose();
    }


}

半透明JTable

public class TranslucentTable extends JTable {

    public TranslucentTable() {
        setOpaque(false);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(getBackground());
        g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
        getUI().paint(g2d, this);
        g2d.dispose();
    }

    @Override
    protected JTableHeader createDefaultTableHeader() {
        JTableHeader header = new TranslucentTableHeader();
        header.setColumnModel(getColumnModel());
        return header;
    }



}

并把它放在一起...

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                String[] colNames = {"Aircraft",
                         "Track ID",
                         "Runway",
                         "Operation Type",
                         "Number Daily of Operations"};
                Object[][] data = {{"Boeing 717",(long) 2459,"01L","Arrival",0.13},{"Boeing 727",(long) 2439,"01R","Arrival",0.12}};

                JTable table = new TranslucentTable();
                DefaultTableModel model = new DefaultTableModel(data, colNames);
                table.setModel(model);

                table.setFont(new Font("Serif", Font.BOLD, 20));
                table.getTableHeader().setFont(new Font("Serif", Font.BOLD, 20));
                table.getTableHeader().setBackground(new Color(0, 0, 0, 100));
                table.getTableHeader().setBorder(BorderFactory.createMatteBorder(3, 3, 3, 3, Color.BLACK));
                table.getTableHeader().setForeground(Color.WHITE);
                table.setRowHeight(table.getRowHeight() + table.getFont().getSize());
                table.setBackground(new Color(214, 217, 223));
                table.setAutoCreateRowSorter(true);
                DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
                centerRenderer.setHorizontalAlignment(SwingConstants.CENTER);

                for (int i = 0; i < colNames.length; i++) {
                    table.getColumnModel().getColumn(i).setCellRenderer(centerRenderer);
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                frame.getContentPane().setBackground(Color.RED);
                TranslucentScrollPane scrollPane = new TranslucentScrollPane();
                scrollPane.setBackground(new Color(0, 0, 0, 200));
                scrollPane.setViewportView(table);

                frame.add(scrollPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}