要使列可编辑,您必须覆盖TableModel 中的isCellEditable 方法。如果您继承 AbstractTableModel,则创建 TableModel 相当容易,除了最简单的 JTables 之外,我建议所有人使用它。
但是,调整TableModel 只是您需要做的一部分。要真正在JTable 中获取自定义组件,您需要设置自定义单元格渲染器。要使用交互式自定义组件,您需要设置自定义单元格编辑器。在某些情况下,为此使用默认类的略微修改版本就足够了。
编辑器
如果您已经有了自定义组件,使用委托可以轻松完成:创建一个实现TableCellEditor 的新类,并在getCellEditorComponent 方法中返回组件的新 实例。此方法的参数包括当前值以及单元格坐标、返回表格的链接以及是否选择了单元格。
TableCellEditor 还有一个方法,当用户提交对单元格内容的更改(您可以在其中验证用户输入和调整模型)或取消编辑时调用该方法。如果您曾经以编程方式中止编辑,请务必在您的编辑器上调用stopEditing() 方法,否则编辑器组件将保留在屏幕上——这曾经花了我大约 2 个小时来调试。
请注意,在JTable 编辑器和仅 编辑器接收事件!可以使用渲染器来显示按钮。但是要获得一个正常工作的按钮,您需要实现一个编辑器并注册了正确的EventListeners。在渲染器上注册监听器没有任何作用。
渲染器
对于您在问题中描述的内容,实施渲染器并不是绝对必要的,但您通常最终还是会这样做,即使只是为了进行微小的修改。与编辑器不同,渲染器对速度至关重要。 渲染器的getTableCellRendererComponent为表格中的每个单元格调用一次!渲染器返回的组件仅用于绘制单元格,不用于交互,因此可以“重用”下一个单元格。换句话说,您应该在渲染器中调整组件(例如,使用setText(...) 或setFont(...),如果它是TextComponent),您应该不实例化一个新组件——这很容易削弱性能的方法。
注意事项
请注意,要使渲染器和编辑器正常工作,您需要告诉JTable 何时使用某个渲染器/编辑器。基本上有两种方法可以做到这一点。您可以使用相应的JTable 方法为特定类型设置默认单元格渲染器/编辑器。要使这种方式起作用,您的 TableModel 需要在 getColumnClass(...) 方法中准确返回此类型!默认表模型不会为您执行此操作,它始终返回 Object.class。我敢肯定,它难倒了很多人。
设置编辑器/渲染器的另一种方法是在列本身上显式设置它,即通过JTable 的getTableColumn(...) 方法获取TableColumn。这要复杂得多,但是,它也是为单个类拥有两个不同的渲染器/编辑器的唯一方法。例如。您的模型可能有两列 String 类,它们以完全不同的方式呈现,可能一次使用 JLabel/DefaultRenderer,另一列使用 JButton 来访问更精细的编辑器。
JTable 及其自定义渲染器和编辑器非常 用途广泛,但它也有很多需要考虑的地方,还有很多事情要做错。祝你好运!
The Swing Tutorial 中的How to Use Tables 是任何自定义 JTables 的必读内容。特别是,阅读和重新阅读Concepts: Editors and Renderers,因为它通常需要一段时间才能“点击”。自定义渲染器和编辑器的例子也很值得。