• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JComboBoxのアイテムを選択不可にする
#navi(../)
#tags(JComboBox, ListCellRenderer, ActionMap, InputMap)
RIGHT:Posted by &author(aterai); at 2008-04-14
* JComboBoxのアイテムを選択不可にする [#q640bc3b]
---
title: JComboBoxのアイテムを選択不可にする
tags: [JComboBox, ListCellRenderer, ActionMap, InputMap]
author: aterai
pubdate: 2008-04-14T13:34:30+09:00
description: JComboBoxのドロップダウンリストで、指定したアイテムを選択不可にします。
---
* 概要 [#q640bc3b]
`JComboBox`のドロップダウンリストで、指定したアイテムを選択不可にします。

#download
#ref(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTLHzjDYpI/AAAAAAAAAXE/M4bkzWJetUI/s800/DisableItemComboBox.png)
#download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTLHzjDYpI/AAAAAAAAAXE/M4bkzWJetUI/s800/DisableItemComboBox.png)

** サンプルコード [#eb0a9dc4]
* サンプルコード [#eb0a9dc4]
#code(link){{
class MyComboBox extends JComboBox {
  public MyComboBox() {
class DisableItemComboBox<E> extends JComboBox<E> {
  private final Set<Integer> disableIndexSet = new HashSet<>();
  private boolean isDisableIndex;
  private final Action up = new AbstractAction() {
    @Override public void actionPerformed(ActionEvent e) {
      int si = getSelectedIndex();
      for (int i = si - 1; i >= 0; i--) {
        if (!disableIndexSet.contains(i)) {
          setSelectedIndex(i);
          break;
        }
      }
    }
  };
  private final Action down = new AbstractAction() {
    @Override public void actionPerformed(ActionEvent e) {
      int si = getSelectedIndex();
      for (int i = si + 1; i < getModel().getSize(); i++) {
        if (!disableIndexSet.contains(i)) {
          setSelectedIndex(i);
          break;
        }
      }
    }
  };
  public DisableItemComboBox() {
    super();
    final ListCellRenderer r = getRenderer();
    setRenderer(new ListCellRenderer() {
      @Override public Component getListCellRendererComponent(JList list,
          Object value, int index, boolean isSelected, boolean cellHasFocus) {
  }
  public DisableItemComboBox(ComboBoxModel<E> aModel) {
    super(aModel);
  }
  public DisableItemComboBox(E[] items) {
    super(items);
  }
  @Override public void updateUI() {
    super.updateUI();
    setRenderer(new DefaultListCellRenderer() {
      @Override public Component getListCellRendererComponent(
          JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Component c;
        if(disableIndexSet.contains(index)) {
          c = r.getListCellRendererComponent(list,value,index,false,false);
        if (disableIndexSet.contains(index)) {
          c = super.getListCellRendererComponent(list, value, index, false, false);
          c.setEnabled(false);
        }else{
          c = r.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus);
        } else {
          c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
          c.setEnabled(true);
        }
        return c;
      }
    });
    Action up = new AbstractAction() {
      @Override public void actionPerformed(ActionEvent e) {
        int si = getSelectedIndex();
        for(int i = si-1;i>=0;i--) {
          if(!disableIndexSet.contains(i)) {
            setSelectedIndex(i);
            break;
          }
        }
      }
    };
    Action down = new AbstractAction() {
      @Override public void actionPerformed(ActionEvent e) {
        int si = getSelectedIndex();
        for(int i = si+1;i<getModel().getSize();i++) {
          if(!disableIndexSet.contains(i)) {
            setSelectedIndex(i);
            break;
          }
        }
      }
    };
    ActionMap am = getActionMap();
    am.put("selectPrevious3", up);
    am.put("selectNext3", down);
    InputMap im = getInputMap();
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),      "selectPrevious3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0),   "selectPrevious3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0),    "selectNext3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, 0), "selectNext3");
  }
  private final HashSet<Integer> disableIndexSet = new HashSet<>();
  private boolean isDisableIndex = false;
  public void setDisableIndex(HashSet<Integer> set) {
  public void setDisableIndex(Set<Integer> set) {
    disableIndexSet.clear();
    for(Integer i:set) {
    for (Integer i : set) {
      disableIndexSet.add(i);
    }
  }
  @Override public void setPopupVisible(boolean v) {
    if(!v && isDisableIndex) {
    if (!v && isDisableIndex) {
      isDisableIndex = false;
    }else{
    } else {
      super.setPopupVisible(v);
    }
  }
  @Override public void setSelectedIndex(int index) {
    if(disableIndexSet.contains(index)) {
    if (disableIndexSet.contains(index)) {
      isDisableIndex = true;
    }else{
    } else {
      //isDisableIndex = false;
      super.setSelectedIndex(index);
    }
  }
}
}}

** 解説 [#qdc48e21]
* 解説 [#qdc48e21]
上記のサンプルでは、以下の方法でドロップダウンリストの特定のアイテムを選択できないように設定しています。

- 表示
-- セルレンダラーで`setEnabled`などを設定
- 選択不可
-- `setSelectedIndex`をオーバーライド
- 選択不可アイテムをクリックしてもポップアップを閉じない
-- `setPopupVisible`をオーバーライド
- キー操作で選択不可アイテムを無視
-- `ActionMap`、`InputMap`の設定

** 参考リンク [#ic0f4012]
* 参考リンク [#ic0f4012]
- [[JListの任意のItemを選択不可にする>Swing/DisabledItem]]

** コメント [#v2920269]
* コメント [#v2920269]
#comment
#comment