• title: JComboBoxのドロップダウンリストで右クリックを無効化 tags: [JComboBox, BasicComboPopup, MouseListener, JList] author: aterai pubdate: 2009-06-29T10:14:32+09:00 description: JComboBoxのドロップダウンリスト(ポップアップメニュー)で、マウスの右クリックを無効にします。

概要

JComboBoxのドロップダウンリスト(ポップアップメニュー)で、マウスの右クリックを無効にします。

サンプルコード

class BasicComboPopup2 extends BasicComboPopup {
  private Handler2 handler2;
  @Override public void uninstallingUI() {
    super.uninstallingUI();
    handler2 = null;
  }
  public BasicComboPopup2(JComboBox combo) {
    super(combo);
  }
  @Override protected MouseListener createListMouseListener() {
    if(handler2==null) handler2 = new Handler2();
    return handler2;
  }
  private class Handler2 implements MouseListener{
    @Override public void mouseEntered(MouseEvent e) {}
    @Override public void mouseExited(MouseEvent e)  {}
    @Override public void mouseClicked(MouseEvent e) {}
    @Override public void mousePressed(MouseEvent e) {}
    @Override public void mouseReleased(MouseEvent e) {
      if(e.getSource() == list) {
        if(list.getModel().getSize() > 0) {
          // <ins>
          if(!SwingUtilities.isLeftMouseButton(e) || !comboBox.isEnabled()) return;
          // </ins>
          // JList mouse listener
          if(comboBox.getSelectedIndex() == list.getSelectedIndex()) {
            comboBox.getEditor().setItem(list.getSelectedValue());
          }
          comboBox.setSelectedIndex(list.getSelectedIndex());
        }
        comboBox.setPopupVisible(false);
        // workaround for cancelling an edited item (bug 4530953)
        if(comboBox.isEditable() && comboBox.getEditor() != null) {
          comboBox.configureEditor(comboBox.getEditor(), comboBox.getSelectedItem());
        }
      }
    }
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、ComboBoxUI#createPopup()をオーバーライドして、ドロップダウンリストに設定するMouseListenerを入れ替えたBasicComboPopupを追加しています。

combo02.setUI(new BasicComboBoxUI() {
  @Override protected ComboPopup createPopup() {
    return new BasicComboPopup2( comboBox );
  }
});

元のMouseListenerは、JComboBox全体のHandlerになっていますが、必要なのはドロップダウンリスト関係のみなので、e.getSource() == listな部分だけ元のHandlerからコピーし、この中でif(!SwingUtilities.isLeftMouseButton(e) || !comboBox.isEnabled()) return;と右クリックを無視しています。


以下のような方法もあります。

class BasicComboPopup3 extends BasicComboPopup {
  public BasicComboPopup3(JComboBox combo) {
    super(combo);
  }
  @Override protected JList createList() {
    return new JList(comboBox.getModel()) {
      @Override public void processMouseEvent(MouseEvent e) {
        if(SwingUtilities.isRightMouseButton(e)) return;
        if(e.isControlDown()) {
          // Fix for 4234053. Filter out the Control Key from the list.
          // ie., don't allow CTRL key deselection.
          Toolkit toolkit = Toolkit.getDefaultToolkit();
          e = new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(),
                     //e.getModifiers() ^ InputEvent.CTRL_MASK,
                     e.getModifiers() ^ toolkit.getMenuShortcutKeyMask(),
                     e.getX(), e.getY(),
                     e.getXOnScreen(), e.getYOnScreen(),
                     e.getClickCount(),
                     e.isPopupTrigger(),
                     MouseEvent.NOBUTTON);
        }
        super.processMouseEvent(e);
      }
    };
  }
}

コメント