Java JTable:单元格中自定义面板中的按钮
我希望能够在一个单元格中有一个JPanel,该单元格中有一个JButton,单击该按钮时可以执行一些操作 我查找了有关单元格编辑器的说明,但所有示例都谈到用另一个组件替换单元格(例如,用JTextField替换int等)。我的情况略有不同: 我有以下ADTJava JTable:单元格中自定义面板中的按钮,java,jtable,jpanel,jbutton,Java,Jtable,Jpanel,Jbutton,我希望能够在一个单元格中有一个JPanel,该单元格中有一个JButton,单击该按钮时可以执行一些操作 我查找了有关单元格编辑器的说明,但所有示例都谈到用另一个组件替换单元格(例如,用JTextField替换int等)。我的情况略有不同: 我有以下ADT class MyClass { public String title; public String url; public String path; public int annotations; } 我创建了一个自定义表
class MyClass {
public String title;
public String url;
public String path;
public int annotations;
}
我创建了一个自定义表格单元模型,它有一列,该列的类是MyClass。然后,我为该类创建了一个单元呈现器,它返回一个JPanel,如下所示:
如您所见,JPanel包含一个按钮。我希望此按钮在单击时启动JFrame。有什么想法吗
如果您建议使用Cell Editor,请详细说明如何使用。如果可能,提供一些伪代码
多谢各位
另外,我很确定这个问题的标题需要一些修改
因此,在监听器中,您必须检查表的选择,以便能够以不同的方式对每一行进行响应。
如果希望将所有元素保留在一列中,可以将JButton替换为包含所有组件的面板。然后,JTable将所有事件转发给该JPanel。之后,我终于完成了我想要的。然而,我想对这个问题有一个更完整的答案,所以我将自己提供一个
因此,单元渲染器只绘制组件,不允许在组件内进行任何交互。而单元格编辑器可以
最初,JTable中的所有单元格都是由注册的呈现程序返回的组件。但是,当选定单元格时,该组件将替换为编辑器返回的组件。这两者实际上可以是不同的组件!我很确定你可以利用这一点,制作一些时髦的细胞: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; }
}
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,但我不确定性能。您可以创建一个包含多个列的表,然后可以添加一个单独的列来包含按钮。该类允许您轻松完成此操作。这是否意味着我不再需要我的CellRenderer?我只是把它做成一个单元格编辑器?不。如果你这样做,一个空白单元格就会被渲染。JTable在内部仅将渲染器用于显示数据。但是如果你点击一个单元格,它将变成可编辑的,由celleditor提供的组件将被显示。是的,我在问过你之后就试过了,事实上就是这样。非常感谢。我希望避免这种情况,因为我希望能够按照自己的意愿(如屏幕截图所示)放置我的组件,而不是一个挨着另一个。这样,拥有两个列可能会更容易。一个用于数据,一个用于按钮。可以从表中删除垂直线,使其看起来仍然像一列。
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 myClassTable = new JTable(new MyClassTableModel());
myClassTable.setDefaultRenderer(MyClass.class, new MyClassCellRenderer());
myClassTable.setDefaultEditor(MyClass.class, new MyClassCellEditor());