JTable AutoCreateRowSorter causes Swing to Paint the table wrong

帅比萌擦擦* 提交于 2020-01-06 07:01:17

问题


I've created a JTable within java and have used AutoCreateRowSorter method to help sort the columns of the table.

The issue is when I click on the column header to sort the table it repaints the table wrong. The first image shown is how it looks when opened. The second image shows what happens when I click once. Notice the data overlaps the column 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;
    }

}

I'm wondering to how fix this issue. Thanks for the help.


回答1:


Swing doesn't know how to deal with alpha based colors as background colors, it's designed to only work with only fully transparent or fully opaque components.

You can fake it, by extending the components, making them transparent and then performing the fill operation yourself

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

}

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


}

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



}

And putting it altogether...

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

}


来源:https://stackoverflow.com/questions/43010330/jtable-autocreaterowsorter-causes-swing-to-paint-the-table-wrong

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!