• category: swing folder: TableCellExpandCollapseOnClick title: JTableのセル内に配置したJCheckBoxをクリックして行の高さの展開・折り畳みを実行する tags: [JTable, TableCellEditor, TableCellRenderer, JCheckBox] author: aterai pubdate: 2023-05-08T00:00:19+09:00 description: JTableのセル内にJCheckBoxを配置し、これをクリックしたらとなりのセルの推奨サイズまで行の高さを展開します。 image: https://drive.google.com/uc?id=16vOMLYeg5yf607l6d6z-mU1d6GMU96m2

概要

JTableのセル内にJCheckBoxを配置し、これをクリックしたらとなりのセルの推奨サイズまで行の高さを展開します。

サンプルコード

int defaultHeight = 20;
JTable table = new JTable(model) {
  @Override public void updateUI() {
    super.updateUI();
    setAutoCreateRowSorter(true);
    setSurrendersFocusOnKeystroke(true);
    setRowHeight(defaultHeight);
    setDefaultRenderer(RowHeader.class, new RowHeaderRenderer());
    setDefaultEditor(RowHeader.class, new RowHeaderEditor());
    TableColumn column = getColumnModel().getColumn(1);
    column.setCellRenderer(new TextAreaCellRenderer());
    column.setPreferredWidth(160);
  }
};
table.getModel().addTableModelListener(e -> {
  int mc = e.getColumn();
  int mr = e.getFirstRow();
  int vc = table.convertColumnIndexToView(mc);
  int vr = table.convertRowIndexToView(mr);
  Object o = table.getValueAt(vr, vc);
  if (mc == 0 && o instanceof RowHeader) {
    RowHeader rh = (RowHeader) o;
    int vc1 = table.convertColumnIndexToView(1);
    TableCellRenderer r = table.getColumnModel().getColumn(vc1)
                               .getCellRenderer();
    Object v = table.getValueAt(vr, vc1);
    Component c = r.getTableCellRendererComponent(
        table, v, true, true, vr, vc1);
    int h = rh.isSelected() ? c.getPreferredSize().height
                            : defaultHeight;
    table.setRowHeight(vr, h);
  }
});
View in GitHub: Java, Kotlin

解説

  • 0列目
    • タイトル文字列、展開折り畳み可能か、現在展開されているかの3つのデータを保持するRowHeaderクラスをColumnClassとして設定
    • JTable#setDefaultRenderer(RowHeader.class, new RowHeaderRenderer())RowHeaderクラスのセルレンダラを設定
    • JTable#setDefaultEditor(RowHeader.class, new RowHeaderEditor())RowHeaderクラスのセルエディタを設定
    • 共にタイトル用のJLabelと展開・折り畳み用のJCheckBoxを配置したJPanelを使用
    • JCheckBoxの選択アイコンは、未選択状態アイコンはの文字表示に変更
  • 1列目
    • 複数行の文字列を表示可能なJTextAreaをセルレンダラとして設定
    • TableCellRenderer#getTableCellRendererComponent(...)内でJTextAreaに文字列を設定し、かつJTextAreaの幅を現在の列のセル幅と同じになるよう設定することでJTextAreaの推奨サイズが計算可能になる
  • TableModelListener
    • 実際の行の高さの展開・折り畳みはRowHeaderの選択状態が変化してTableModelEventが発生したときにJTable#setRowHeight(...)メソッドで実行する
    • JTableの行の高さを変更する

参考リンク

コメント