Trying to create JTable with proper row header

后端 未结 2 789
礼貌的吻别
礼貌的吻别 2020-12-01 16:28

I am trying to create a JTable that has a row header that looks just like a column header and I have spent altogether too much time on it :/ My situation is similar to this

相关标签:
2条回答
  • 2020-12-01 17:06

    maybe

    enter image description here

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import javax.swing.*;
    import javax.swing.UIManager.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    
    public class JTableRowHeader {
    
        private JFrame frame = new JFrame("JTable RowHeader");
        private JScrollPane scrollPane;
        private JTable table;
        private DefaultTableModel model;
        private TableRowSorter<TableModel> sorter;
        private JTable headerTable;
    
        public JTableRowHeader() {
            table = new JTable(4, 4);
            for (int i = 0; i < table.getRowCount(); i++) {
                table.setValueAt(i, i, 0);
            }
            sorter = new TableRowSorter<TableModel>(table.getModel());
            table.setRowSorter(sorter);
            model = new DefaultTableModel() {
    
                private static final long serialVersionUID = 1L;
    
                @Override
                public int getColumnCount() {
                    return 1;
                }
    
                @Override
                public boolean isCellEditable(int row, int col) {
                    return false;
                }
    
                @Override
                public int getRowCount() {
                    return table.getRowCount();
                }
    
                @Override
                public Class<?> getColumnClass(int colNum) {
                    switch (colNum) {
                        case 0:
                            return String.class;
                        default:
                            return super.getColumnClass(colNum);
                    }
                }
            };
            headerTable = new JTable(model);
            for (int i = 0; i < table.getRowCount(); i++) {
                headerTable.setValueAt("Row " + (i + 1), i, 0);
            }
            headerTable.setShowGrid(false);
            headerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            headerTable.setPreferredScrollableViewportSize(new Dimension(50, 0));
            headerTable.getColumnModel().getColumn(0).setPreferredWidth(50);
            headerTable.getColumnModel().getColumn(0).setCellRenderer(new TableCellRenderer() {
    
                @Override
                public Component getTableCellRendererComponent(JTable x, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    
                    boolean selected = table.getSelectionModel().isSelectedIndex(row);
                    Component component = table.getTableHeader().getDefaultRenderer().getTableCellRendererComponent(table, value, false, false, -1, -2);
                    ((JLabel) component).setHorizontalAlignment(SwingConstants.CENTER);
                    if (selected) {
                        component.setFont(component.getFont().deriveFont(Font.BOLD));
                        component.setForeground(Color.red);
                    } else {
                        component.setFont(component.getFont().deriveFont(Font.PLAIN));
                    }
                    return component;
                }
            });
            table.getRowSorter().addRowSorterListener(new RowSorterListener() {
    
                @Override
                public void sorterChanged(RowSorterEvent e) {
                    model.fireTableDataChanged();
                }
            });
            table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
    
                @Override
                public void valueChanged(ListSelectionEvent e) {
                    model.fireTableRowsUpdated(0, model.getRowCount() - 1);
                }
            });
            scrollPane = new JScrollPane(table);
            scrollPane.setRowHeaderView(headerTable);
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.add(scrollPane);
            frame.add(new JButton(new AbstractAction("Toggle filter") {
    
                private static final long serialVersionUID = 1L;
                private RowFilter<TableModel, Object> filter = new RowFilter<TableModel, Object>() {
    
                    @Override
                    public boolean include(javax.swing.RowFilter.Entry<? extends TableModel, ? extends Object> entry) {
                        return ((Number) entry.getValue(0)).intValue() % 2 == 0;
                    }
                };
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (sorter.getRowFilter() != null) {
                        sorter.setRowFilter(null);
                    } else {
                        sorter.setRowFilter(filter);
                    }
                }
            }), BorderLayout.SOUTH);
            frame.pack();
            frame.setLocation(150, 150);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            try {// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                    if (info.getName().equals("Nimbus")) {
                        UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (Exception e) {
                //e.printStackTrace();
            }
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    JTableRowHeader TestTableRowHeader = new JTableRowHeader();
                }
            });
        }
    }
    

    Here it is with system Look and Feel- enter image description here

    0 讨论(0)
  • 2020-12-01 17:29

    Using this HeaderRenderer as the first row column renderer may produce the effect you want:

    Addendum: I've updated the example to reflect your sscce with a manual layout. My platform's getSystemLookAndFeelClassName() is com.apple.laf.AquaLookAndFeel, so I'm not seeing the same result. Two observations: You've already setAutoCreateRowSorter(false) to prevent the sorting widget from proliferating, and Nimbus retains it alternating row highlight.

    enter image description here

    import java.awt.Component;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.JTableHeader;
    import javax.swing.table.TableCellRenderer;
    
    public class MyTableExample3 extends JFrame {
    
        private JScrollPane scrollPane;
        private JTable table;
    
        public MyTableExample3() {
            initComponents();
        }
    
        @SuppressWarnings("unchecked")
        private void initComponents() {
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            table = new javax.swing.JTable() {
    
                @Override
                public Component prepareRenderer(
                    TableCellRenderer renderer, int row, int col) {
                    if (col == 0) {
                        return this.getTableHeader().getDefaultRenderer()
                            .getTableCellRendererComponent(this, this.getValueAt(
                                row, col), false, false, row, col);
                    } else {
                        return super.prepareRenderer(renderer, row, col);
                    }
                }
            };
            table.setAutoCreateRowSorter(false);
            final JTableHeader header = table.getTableHeader();
            header.setDefaultRenderer(new HeaderRenderer(table));
    
            table.setModel(new javax.swing.table.DefaultTableModel(
                new Object[][]{
                    {"Row 1", "Data 2", "Data 3", "Data 4", "Data 5"},
                    {"Row 2", "Data 6", "Data 7", "Data 8", "Data 9"},
                    {"Row 3", "Data 10", "Data 11", "Data 12", "Data 13"}
                },
                new String[]{
                    "", "Col 1", "Col 2", "Col 3", "Col 4"
                }));
            scrollPane = new JScrollPane(table);
            this.add(scrollPane);
            pack();
        }
    
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new MyTableExample3().setVisible(true);
                }
            });
        }
    
        private static class HeaderRenderer implements TableCellRenderer {
    
            TableCellRenderer renderer;
    
            public HeaderRenderer(JTable table) {
                renderer = table.getTableHeader().getDefaultRenderer();
            }
    
            @Override
            public Component getTableCellRendererComponent(
                JTable table, Object value, boolean isSelected,
                boolean hasFocus, int row, int col) {
                return renderer.getTableCellRendererComponent(
                    table, value, isSelected, hasFocus, row, col);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题