简体   繁体   中英

JTable AutoCreateRowSorter causes Swing to Paint the table wrong

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.

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM