coding.mofの返信の後、私はついにやりたいことをしました。ただし、この質問に対するより完全な回答が必要だったので、自分で回答します。
したがって、セルレンダラーはコンポーネントを描画するだけで、コンポーネント内での相互作用を許可しません。セルエディタはそうしますが。
最初、JTableのすべてのセルは、登録されたレンダラーによって返されるコンポーネントです。ただし、セルを選択すると、このコンポーネントはエディターによって返されるコンポーネントに置き換えられます。これら2つは、実際には異なるコンポーネントである可能性があります。これを利用して、ファンキーなセルを作成できると確信しています: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());
これで完了です。
PSレンダラーとエディターを1つのクラスに組み合わせて、AbstractCellEditorを拡張し、TableCellRendererを実装できると確信していますが、パフォーマンスについてはよくわかりません。