• category: swing folder: PropertyTable title: JTableでプロパティ一覧表を作成する tags: [JTable, TableCellRenderer, TableCellEditor, JColorChooser] author: aterai pubdate: 2014-01-06T00:25:50+09:00 description: JTableの行ごとにクラスに応じたセルエディタなどを適用することで、プロパティ一覧表を作成します。 image: https://lh4.googleusercontent.com/-ZueCWsZFbOQ/UslO6WVldNI/AAAAAAAAB9g/53vsd2t0OPo/s800/PropertyTable.png

概要

JTableの行ごとにクラスに応じたセルエディタなどを適用することで、プロパティ一覧表を作成します。

サンプルコード

String[] columnNames = {"Type", "Value"};
Object[][] data = {
  {"String",  "text"      },
  {"Date",    new Date()  },
  {"Integer", 12          },
  {"Double",  3.45        },
  {"Boolean", Boolean.TRUE},
  {"Color",   Color.RED   }
};
JTable table = new JTable(data, columnNames) {
  private Class editingClass;
  private Class getClassAt(int row, int column) {
    int mc = convertColumnIndexToModel(column);
    int mr = convertRowIndexToModel(row);
    return getModel().getValueAt(mr, mc).getClass();
  }
  @Override public TableCellRenderer getCellRenderer(int row, int column) {
    //editingClass = null;
    if (convertColumnIndexToModel(column) == 1) {
      //System.out.println("getCellRenderer");
      return getDefaultRenderer(getClassAt(row, column));
    } else {
      return super.getCellRenderer(row, column);
    }
  }
  @Override public TableCellEditor getCellEditor(int row, int column) {
    if (convertColumnIndexToModel(column) == 1) {
      //System.out.println("getCellEditor");
      editingClass = getClassAt(row, column);
      return getDefaultEditor(editingClass);
    } else {
      editingClass = null;
      return super.getCellEditor(row, column);
    }
  }
  // https://stackoverflow.com/questions/1464691/property-list-gui-component-in-swing
  // This method is also invoked by the editor when the value in the editor
  // component is saved in the TableModel. The class was saved when the
  // editor was invoked so the proper class can be created.
  @Override public Class getColumnClass(int column) {
    //return editingClass != null ? editingClass : super.getColumnClass(column);
    if (convertColumnIndexToModel(column) == 1) {
      //System.out.println("getColumnClass");
      return editingClass;
    } else {
      return super.getColumnClass(column);
    }
  }
};
table.setAutoCreateRowSorter(true);
table.setDefaultRenderer(Color.class, new ColorRenderer());
table.setDefaultEditor(Color.class,   new ColorEditor());
table.setDefaultEditor(Date.class,    new DateEditor());
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JTable#getCellRenderer(...)JTable#getCellEditor(...)をオーバーライドして、実際のモデル値からクラスを取得し、そのクラスに応じて行ごとに使用するセルレンダラー、セルエディタを変更しています。

  • セルレンダラー
    • StringクラスとDateクラスは、デフォルトのDefaultTableCellRendererを使用
    • IntegerクラスとDoubleクラスは、デフォルトのJTable$NumberRendererを使用
    • Colorクラスは、アイコンで色を表示するセルレンダラーを作成してTable#setDefaultRenderer(Color.class, new ColorRenderer())で設定
  • セルエディタ
    • Stringクラスは、デフォルトのJTable$GenericEditorを使用
    • IntegerクラスとDoubleクラスは、デフォルトのJTable$NumberEditorを使用
    • Booleanクラスは、デフォルトのJTable$BooleanEditorを使用
    • Dateクラスは、JSpinnerでセルエディタを作成してJTable#setDefaultEditor(Class, TableCellEditor)で設定
    • Colorクラスは、JColorChooserを開くJButtonでセルエディタを作成してJTable#setDefaultEditor(Class, TableCellEditor)で設定

参考リンク

コメント