JComboBoxのドロップダウンリスト中にあるアイテムの状態を更新する
Total: 5544
, Today: 2
, Yesterday: 6
Posted by aterai at
Last-modified:
概要
JComboBox
のドロップダウンリスト中に設定されたアイテムの状態と描画を更新します。
Screenshot
Advertisement
サンプルコード
class CheckableComboBoxModel<E> extends DefaultComboBoxModel<E> {
protected CheckableComboBoxModel(E[] items) {
super(items);
}
public void fireContentsChanged(int index) {
super.fireContentsChanged(this, index, index);
}
}
class CheckedComboBox4<E extends CheckableItem> extends CheckedComboBox<E> {
protected CheckedComboBox4(ComboBoxModel<E> aModel) {
super(aModel);
}
@Override protected void updateItem(int index) {
if (isPopupVisible()) {
E item = getItemAt(index);
item.selected ^= true;
ComboBoxModel m = getModel();
if (m instanceof CheckableComboBoxModel) {
((CheckableComboBoxModel) m).fireContentsChanged(index);
}
}
}
}
View in GitHub: Java, Kotlin解説
JComboBox
のBasicComboPopup
に表示されるリストはJList
を使用しているため、マウスでクリックされたアイテムの状態を更新(上記のサンプルではJCheckBox
の選択状態の切替)してもセルレンダラーでの描画は更新されません(同じアイテムがクリックされても再描画しないため)。
このサンプルでは、JComboBox
のアイテムの更新を描画に反映させるために以下のような方法をテストしています。
setSelectedIndex(-1/idx)
JComboBox#setSelectedIndex(-1)
メソッドを使用して選択解除後、クリックされたアイテムを再選択することで描画を更新- 参考: JComboBoxのアイテムとして表示したJCheckBoxを複数選択する
contentsChanged(...)
JComboBox#contentsChanged(ListDataEvent)
メソッドを使用してクリックされたアイテムのみ更新しようとしているが意図した動作にならない- JComboBox#contentsChanged(ListDataEvent) (Java Platform SE 8)
repaint()
- アイテム更新後、
JComboBox
とBasicComboPopup
から取得したJList
の両方のrepaint()
メソッドを実行して全体を再描画 - 参考: JComboBoxにAnimated GIFを表示する
list.repaint(list.getCellBounds(index, index));
を使用して再描画範囲を限定することも可能
- アイテム更新後、
(remove/insert)ItemAt(...)
JComboBox#removeItemAt(...)
でアイテムを削除、JComboBox#insertItemAt(...)
で状態を更新したアイテムを元の場所に挿入、JComboBox#setSelectedIndex(...)
で挿入されたアイテムを再選択することで描画を更新
fireContentsChanged(...)
DefaultComboBoxModel#fireContentsChanged(...)
メソッドはprotected
で直接呼び出せないため、これを呼び出し可能するラッパーComboBoxModel
を作成してJComboBox
に設定してクリックされたアイテムのみ描画を更新
参考リンク
- JComboBoxのアイテムとして表示したJCheckBoxを複数選択する
- JListのセルにJCheckBoxを使用する
- こちらは
JList#processMouseEvent(...)
をオーバーライドして対応
- こちらは