【问题标题】:JTable with titled rows and columns带有标题行和列的 JTable
【发布时间】:2012-01-01 12:36:07
【问题描述】:

如何让 JTable 的列和行都有标题?
像这样:

+------+------+------+------+
|/\/\/\| col1 | col2 | col3 |
+------+------+------+------+
| row1 |      |      |      |
+------+------+------+------+
| row2 |      |      |      |
+------+------+------+------+
| row3 |      |      |      |
+------+------+------+------+

谢谢

【问题讨论】:

  • 你有没有尝试过?我建议您阅读以下教程:link.

标签: java swing jtable


【解决方案1】:

在 mKorbel 的解决方案中,行标题和表值不同步。过滤后,表格显示第 1 行和第 2 行,而不是第 1 行和第 3 行。

这是基于他的示例的解决方案。它将行标题复制到表中的新列中,隐藏该列并在过滤时将值复制到另一列。

它有效,但很丑陋,我们需要有人提供更好的解决方案:)

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, 5);
        for (int i = 0; i < table.getRowCount(); i++) {
            table.setValueAt("Row " + (i + 1), i, 0);
            table.setValueAt(i, i, 1);
        }
        sorter = new TableRowSorter<TableModel>(table.getModel());
        table.setRowSorter(sorter);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        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();
                for (int i = 0; i < table.getRowCount(); i++) {
                    headerTable.setValueAt(table.getValueAt(i, 0), i, 0);
                }
            }
        });
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                model.fireTableRowsUpdated(0, model.getRowCount() - 1);
            }
        });

        TableColumnModel columnModel = table.getColumnModel();
        TableColumn column = columnModel.getColumn(0);
        column.setMinWidth(0);
        column.setMaxWidth(0);
        column.setPreferredWidth(0);

        AdjusterTableColumn columnAdjuster = new AdjusterTableColumn(table);
        columnAdjuster.adjustColumns();

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

【讨论】:

    【解决方案2】:

    我认为你在搜索 RowTable

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

    【讨论】:

    • 但与@camickrs tips4java.wordpress.com/2008/11/18/row-number-table相比,我的代码是学龄前代码
    • 不错。我想这个问题会是你的拿手好戏。
    • 表头可以显示第1行和第3行而不是第1行和第2行吗?
    • @Ron Ron 是的,因为在 public boolean include(javax.swing.RowFilter.Entry&lt;? extends TableModel, ? extends Object&gt; entry) { 内有硬编码的 return ((Number) entry.getValue(0)).intValue() % 2 == 0;,代码采用 SSCCE / MCVE 形式
    • 我在下面提出了一个版本,过滤后显示对应的行标题(硬编码和动态数据)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    相关资源
    最近更新 更多