Swing/UpdateComboBoxItem のバックアップ(No.2)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/UpdateComboBoxItem へ行く。
- 1 (2017-06-12 (月) 17:15:03)
- 2 (2018-02-15 (木) 14:23:42)
- 3 (2018-06-06 (水) 20:32:55)
- 4 (2020-05-31 (日) 21:10:03)
- 5 (2021-11-14 (日) 03:49:42)
- category: swing folder: UpdateComboBoxItem title: JComboBoxのドロップダウンリスト中にあるアイテムの状態を更新する tags: [JComboBox, JList, JCheckBox, BasicComboPopup, DefaultComboBoxModel] author: aterai pubdate: 2017-06-12T17:11:53+09:00 description: JComboBoxのドロップダウンリスト中に設定されたアイテムの状態と描画を更新します。 image: https://drive.google.com/uc?export=view&id=1R3XuZTHSo7KbYggs0QI2iKVrHHBawo6f2A
概要
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(...)
をオーバーライドして対応
- こちらは