创建具有多个列标题和行标题的自定义TableModel

我正在尝试创建一个看起来像下面的模型的JTable:

自定义JTable

绿色角基本上是红色列和行标题的缓冲空间。 细胞不需要以图中的颜色呈现; 但是它们需要与表中其他“白色”细胞区分开来。

该表也不可编辑或可选择; 它只是在用户更新时才被用户查看。

我知道这可以使用DefaultTableModel实现,其中自定义渲染用于行1,2 && cols 1,2并在设置和获取表值时添加+2(考虑用作标题的行和列)。

我的问题如下:

  1. 有没有一种更简洁的方法来做这个而不用标题中使用的这些静态值污染我的表模型?
  2. 我已经阅读了关于扩展表模型但是我不确定应该扩展哪个类(DefaultTableModel,AbstractTableModel)以及我应该覆盖哪些方法。

输入限制为20×20,因此包括22×22的标头。

还要考虑一个包含JPanelJScrollPane包含GridLayout并包含22×22个实例JLabel或一个合适的子类。 这容易扩展到几千个细胞。

附录:如果需要, CellRendererPane会制作一个好的flyweight渲染器,如此处所示 。

如果你使用JTable来渲染可伸缩性,

  1. 这不是滥用; 这正是TableModel用途。 TableModel模拟您决定的矩形矩阵。 JTable只是该模型的(有效渲染)视图。

  2. 我更喜欢这里显示的AbstractTableModel ,因为Vector很少是理想的数据结构。 使用任何容器使您的索引最方便。 DefaultTableModel非常方便,可作为扩展AbstractTableModel的指南。 特别是,您需要一个setValueAt()

     @Override public void setValueAt(Object aValue, int row, int col) { ... // update your data structure this.fireTableCellUpdated(row, col); // notify the view } 

更长的评论,一切都取决于

1)如果Columns可能

  • 调整

  • 重新排序

2)如果Columns可能

  • 滤波

  • 排序

一个。 然后你看看两个JTable,第一个JTable只有TableHeader,简单的删除行和第二个全尺寸JTable与TableHeader和列和行,

湾 对于两个JTableHeader之间的交互是有的
TableColumnModelListener#columnMarginChanged(ChangeEvent e)和columnMoved(TableColumnModelEvent e)

C。 每个人都在JScrollPane里面放一个JPanel

d。 如果你要更改行数或列数(或过滤/排序),那么你必须通知JPanel重新调整JTable#getPreferredScrollableViewportSize() + Dimension for ontop JTable只能使用TableHeader

非常类似的方式(你需要的一切)

在此处输入图像描述在此处输入图像描述在此处输入图像描述

(Rob的无尽荣誉)

 import java.awt.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; public class TableFilterRow extends JFrame implements TableColumnModelListener { private static final long serialVersionUID = 1L; private JTable table; private JPanel filterRow; public TableFilterRow() { table = new JTable(3, 5); table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane scrollPane = new JScrollPane(table); getContentPane().add(scrollPane); table.getColumnModel().addColumnModelListener(this); // Panel for text fields filterRow = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0)); for (int i = 0; i < table.getColumnCount(); i++) { filterRow.add(new JTextField(" Sum at - " + i)); } columnMarginChanged(new ChangeEvent(table.getColumnModel())); getContentPane().add(filterRow, BorderLayout.SOUTH); } // Implement TableColumnModelListener methods // (Note: instead of implementing a listener you should be able to // override the columnMarginChanged and columMoved methods of JTable) @Override public void columnMarginChanged(ChangeEvent e) { TableColumnModel tcm = table.getColumnModel(); int columns = tcm.getColumnCount(); for (int i = 0; i < columns; i++) { JTextField textField = (JTextField) filterRow.getComponent(i); Dimension d = textField.getPreferredSize(); d.width = tcm.getColumn(i).getWidth(); textField.setPreferredSize(d); } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { filterRow.revalidate(); } }); } @Override public void columnMoved(TableColumnModelEvent e) { Component moved = filterRow.getComponent(e.getFromIndex()); filterRow.remove(e.getFromIndex()); filterRow.add(moved, e.getToIndex()); filterRow.validate(); } @Override public void columnAdded(TableColumnModelEvent e) { } @Override public void columnRemoved(TableColumnModelEvent e) { } @Override public void columnSelectionChanged(ListSelectionEvent e) { } public static void main(String[] args) { JFrame frame = new TableFilterRow(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } } 

3)否则看看如何在prepareRederer 使用凸起边框

4)这个问题与TableModel类型无关