Swing/TableModelEvent のバックアップ(No.3)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TableModelEvent へ行く。
- 1 (2014-05-09 (金) 17:17:04)
- 2 (2014-11-05 (水) 04:55:13)
- 3 (2015-12-08 (火) 15:18:36)
- 4 (2017-06-04 (日) 13:17:03)
- 5 (2018-05-24 (木) 16:25:29)
- 6 (2020-05-20 (水) 09:11:55)
- 7 (2021-11-09 (火) 00:45:48)
- 8 (2025-01-03 (金) 08:57:02)
- 9 (2025-01-03 (金) 09:01:23)
- 10 (2025-01-03 (金) 09:02:38)
- 11 (2025-01-03 (金) 09:03:21)
- 12 (2025-01-03 (金) 09:04:02)
- title: JTableのモデルが変更されたことをイベントで受け取る tags: [JTable, TableModelListener, TableModelEvent, JCheckBox] author: aterai pubdate: 2014-03-31T00:21:38+09:00 description: JTableのモデルの変更を受け取ってJTableHeaderに追加したJCheckBoxを更新します。
概要
JTable
のモデルの変更を受け取ってJTableHeader
に追加したJCheckBox
を更新します。
Screenshot

Advertisement
サンプルコード
class HeaderCheckBoxHandler implements TableModelListener {
private final JTable table;
private final int targetColumnIndex;
public HeaderCheckBoxHandler(JTable table, int index) {
this.table = table;
this.targetColumnIndex = index;
}
@Override public void tableChanged(TableModelEvent e) {
int vci = table.convertColumnIndexToView(targetColumnIndex);
TableColumn column = table.getColumnModel().getColumn(vci);
Object status = column.getHeaderValue();
TableModel m = table.getModel();
if (e.getType() == TableModelEvent.DELETE) {
if (m.getRowCount() == 0) {
column.setHeaderValue(Status.DESELECTED);
} else if (Status.INDETERMINATE.equals(status)) {
boolean selected = true;
boolean deselected = true;
for (int i = 0; i < m.getRowCount(); i++) {
Boolean b = (Boolean) m.getValueAt(i, targetColumnIndex);
selected &= b;
deselected &= !b;
}
if (deselected) {
column.setHeaderValue(Status.DESELECTED);
} else if (selected) {
column.setHeaderValue(Status.SELECTED);
} else {
return;
}
}
} else if (e.getType() == TableModelEvent.INSERT
&& !Status.INDETERMINATE.equals(status)) {
boolean selected = Status.DESELECTED.equals(status);
boolean deselected = Status.SELECTED.equals(status);
for (int i = e.getFirstRow(); i <= e.getLastRow(); i++) {
Boolean b = (Boolean) m.getValueAt(i, targetColumnIndex);
selected &= b;
deselected &= !b;
}
if (selected && m.getRowCount() == 1) {
column.setHeaderValue(Status.SELECTED);
} else if (selected || deselected) {
column.setHeaderValue(Status.INDETERMINATE);
}
} else if (e.getType() == TableModelEvent.UPDATE
&& e.getColumn() == targetColumnIndex) {
if (Status.INDETERMINATE.equals(status)) {
boolean selected = true;
boolean deselected = true;
for (int i = 0; i < m.getRowCount(); i++) {
Boolean b = (Boolean) m.getValueAt(i, targetColumnIndex);
selected &= b;
deselected &= !b;
if (selected == deselected) {
return;
}
}
if (deselected) {
column.setHeaderValue(Status.DESELECTED);
} else if (selected) {
column.setHeaderValue(Status.SELECTED);
} else {
return;
}
} else {
column.setHeaderValue(Status.INDETERMINATE);
}
}
JTableHeader h = table.getTableHeader();
h.repaint(h.getHeaderRect(vci));
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、0
行目の値(boolean
)の変更、行の追加、削除を受け取ってJTableHeader
のチェック状態を更新するTableModelListener
を作成して、これをTableModel#addTableModelListener(...)
で設定しています。
e.getType() == TableModelEvent.DELETE
: 行の削除- 削除によって行数が
0
になった場合は、JTableHeader
は未選択状態 JTableHeader
が選択状態、または未選択状態の場合、削除によってその状態は変化しないJTableHeader
が不定状態の場合は、全行を検索して選択状態を変更するかどうかを調査する
- 削除によって行数が
e.getType() == TableModelEvent.INSERT
: 行の追加JTableHeader
がすでに不定状態の場合は、追加される行の選択状態にかかわらず、その状態は変化しないJTableHeader
が不定状態でない場合は、追加される行とJTableHeader
の選択状態を合わせて調査する
e.getType() == TableModelEvent.UPDATE
:0
列目の更新JTableHeader
が不定状態の場合は、全行を検索して選択状態を変更するかどうかを調査するJTableHeader
が不定状態でない場合は、この更新によってJTableHeader
は不定状態になる