После ответа coding.mof я наконец сделал то, что хотел.Однако я хотел получить более полный ответ на этот вопрос, поэтому я сам предоставлю его.
Итак, средства визуализации ячеек просто рисуют компонент и не допускают никаких взаимодействий внутри него.В то время как сотовые редакторы делают.
Первоначально все ячейки в JTable являются компонентами, которые возвращаются зарегистрированным средством визуализации.Однако при выборе ячейки этот компонент заменяется компонентом, возвращаемым редактором.Эти два могут фактически быть различными компонентами!Я уверен, что вы можете воспользоваться этим и создать несколько прикольных ячеек: P
В любом случае, в этом примере и рендер, и редактор отображают один и тот же компонент, поэтому мы создадим компонент, который будетиспользоваться обоими.
Во-первых, нам нужно создать TableModel, который возвращает нашу ADT:
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; }
}
Теперь мы создадим компонент, который будет использоваться совместно с Renderer и Editor:
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());
И мы закончили!
PS Я почти уверен, что мы можем объединить Renderer и Editor в один классон расширяет AbstractCellEditor и реализует TableCellRenderer, но я не уверен насчет производительности.