我希望能够在带有 JButton 的单元格中放置一个 JPanel,该 JButton 在单击时执行某些操作。
我查找了有关 Cell Editors 的 howtos,但所有示例都在谈论用另一个组件替换单元格(例如,用 JTextField 替换 int 等)。我的情况有点不同:
我有以下ADT
class MyClass {
public String title;
public String url;
public String path;
public int annotations;
}
我创建了一个包含 1 列的自定义表格单元格模型,该列的类是 MyClass。然后我为该类创建了一个单元格渲染器,它返回一个 JPanel,如下所示:
如您所见,JPanel 包含一个按钮。我希望此按钮在单击时启动 JFrame。有什么想法吗?
如果您建议使用 Cell Editor,请更具体地说明如何操作。如果可能,请提供一些伪代码。
谢谢。
附言我很确定这个问题的标题需要一些工作。 ;)
最佳答案
在 coding.mof's reply 之后,我终于如愿以偿了。但是,我想对这个问题有一个更完整的答案,所以我会自己提供一个。
因此,Cell Renderer 只是简单地绘制组件,不允许在其中进行任何交互。而单元格编辑器则可以。
最初,JTable 中的所有单元格都是由已注册渲染器返回的组件。 However, when a cell is selected, this component is replaced by a component that is returned by the editor.这两个实际上可以是不同的组件!我很确定你可以利用它来制作一些时髦的细胞 :P
无论如何,在这个例子中,渲染器和编辑器都显示相同的组件,所以我们将创建一个将由两者使用的组件。
首先,我们需要创建一个返回我们的 ADT 的 TableModel:
class MyClassTableModel extends DefaultTableModel {
List<MyClass> data;
public MyClassTableModel(List<MyClass> data) {
this.data = data;
}
public Class<?> getColumnClass(int columnIndex) { return MyClass.class; }
public int getColumnCount() { return 1; }
public String getColumnName(int columnIndex) { return "MyClass"; }
public int getRowCount() { return (data == null) ? 0 : data.size(); }
public Object getValueAt(int rowIndex, int columnIndex) { return data.get(rowIndex); }
public boolean isCellEditable(int rowIndex, int columnIndex) { return true; }
}
现在,我们创建一个将在渲染器和编辑器之间共享的组件:
class MyClassCellComponent extends JPanel() {
MyClass myClass;
public MyClassCellComponent() {
// initialize components (labels, buttons, etc.)
// add action listeners
}
public void updateData(MyClass myClass, boolean isSelected, JTable table) {
this.myClass = myClass;
// update buttons, labels etc. accordingly
}
}
isSelected 和table 参数用于渲染面板的背景,是可选的。以下是渲染器如何使用我们的组件:
class MyClassCellRenderer implements TableCellRenderer {
MyClassCellComponent panel;
public MyClassCellRenderer() {
panel = new MyClassCellComponent();
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
MyClass myClass = (MyClass)value;
panel.updateData(myClass, isSelected, table);
return panel;
}
}
下面是编辑器如何使用它:
class MyClassCellEditor extends AbstractCellEditor {
MyClassCellComponent panel;
public MyClassCellEditor() {
panel = new MyClassCellComponent();
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
MyClass myClass = (MyClass)value;
panel.updateData(myClass, true, table);
return panel;
}
public Object getCellEditorValue() {
return null;
}
}
就是这样。现在我们可以简单地创建一个 JTable,如下所示:
JTable myClassTable = new JTable(new MyClassTableModel());
myClassTable.setDefaultRenderer(MyClass.class, new MyClassCellRenderer());
myClassTable.setDefaultEditor(MyClass.class, new MyClassCellEditor());
我们完成了!
附言我很确定我们可以将渲染器和编辑器组合成一个类,扩展 AbstractCellEditor 并实现 TableCellRenderer,但我不确定性能。
关于java - JTable:单元格中自定义面板中的按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3606864/