Swing/DisableRightClick のバックアップソース(No.22)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/DisableRightClick へ行く。
- 1 (2009-06-29 (月) 10:14:32)
- 2 (2009-06-29 (月) 15:24:05)
- 3 (2009-07-10 (金) 14:40:52)
- 4 (2011-05-10 (火) 23:25:48)
- 5 (2011-05-20 (金) 15:51:37)
- 6 (2012-04-24 (火) 18:28:39)
- 7 (2012-04-24 (火) 19:28:45)
- 8 (2013-01-09 (水) 20:44:55)
- 9 (2013-05-03 (金) 23:49:12)
- 10 (2013-08-20 (火) 14:36:40)
- 11 (2014-11-01 (土) 00:46:09)
- 12 (2014-11-26 (水) 16:59:53)
- 13 (2014-11-30 (日) 00:51:50)
- 14 (2015-05-07 (木) 15:59:46)
- 15 (2017-03-09 (木) 16:37:10)
- 16 (2017-06-07 (水) 15:35:06)
- 17 (2017-11-02 (木) 15:34:40)
- 18 (2018-01-11 (木) 18:08:15)
- 19 (2018-02-24 (土) 19:51:30)
- 20 (2018-12-07 (金) 15:18:28)
- 21 (2019-05-22 (水) 19:35:38)
- 22 (2020-03-16 (月) 00:39:33)
- 23 (2021-06-13 (日) 01:25:41)
- 24 (2022-08-20 (土) 22:15:25)
--- category: swing folder: DisableRightClick title: JComboBoxのドロップダウンリストで右クリックを無効化 tags: [JComboBox, BasicComboPopup, MouseListener, JList] author: aterai pubdate: 2009-06-29T10:14:32+09:00 description: JComboBoxのドロップダウンリスト(ポップアップメニュー)で、マウスの右クリックを無効にします。 image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTLKTBLgQI/AAAAAAAAAXI/mV-Gw1hPSYU/s800/DisableRightClick.png hreflang: href: https://java-swing-tips.blogspot.com/2009/06/disable-right-click-in-jcombobox.html lang: en --- * 概要 [#summary] `JComboBox`のドロップダウンリスト(ポップアップメニュー)で、マウスの右クリックを無効にします。 #download(https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTLKTBLgQI/AAAAAAAAAXI/mV-Gw1hPSYU/s800/DisableRightClick.png) * サンプルコード [#sourcecode] #code(link){{ class BasicComboPopup2 extends BasicComboPopup { private transient 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 extends MouseAdapter { @Override public void mouseReleased(MouseEvent e) { if (e.getSource().equals(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()); } } } } } }} * 解説 [#explanation] 上記のサンプルでは、`ComboBoxUI#createPopup()`をオーバーライドして、ドロップダウンリストに設定する`MouseListener`を入れ替えた`BasicComboPopup`を追加しています。 #code{{ 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;`と右クリックを無視しています。 ---- 以下のような方法もあります。 #code{{ class BasicComboPopup3 extends BasicComboPopup { @SuppressWarnings("unchecked") @Override protected JList createList() { return new JList(comboBox.getModel()) { @Override public void processMouseEvent(MouseEvent e) { if (SwingUtilities.isRightMouseButton(e)) { return; } MouseEvent ev = e; 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(); ev = new MouseEvent(e.getComponent(), 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(ev); } }; } } }} * 参考リンク [#reference] - [https://bugs.openjdk.java.net/browse/JDK-4249731 JDK-4249731 JComboBox (Windows L&F), right mouse click selects in menu - Java Bug System] -- 要望が矛盾しているとして却下されているが、もしかしたら「`Windows`環境の標準動作に合わせて、`WindowsLookAndFeel`の`JComboBox`では右クリックしてもドロップダウンリストを閉じないようにして欲しい」との意味だったのかもしれない * コメント [#comment] #comment - ドロップダウンリストにスクロールバーが表示されていない場合、ホイールを回すとポップアップが閉じてしまうのも地味に困る…。[https://bugs.openjdk.java.net/browse/JDK-8033069 JDK-8033069 mouse wheel scroll closes combobox popup - Java Bug System] -- &user(aterai); &new{2012-04-24 (火) 18:28:39}; #code{{ //Test class BasicComboPopup3 extends BasicComboPopup { public BasicComboPopup3(JComboBox combo) { super(combo); } @Override protected JScrollPane createScroller() { JScrollPane sp = new JScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER) { @Override protected void processEvent(AWTEvent e) { if (e instanceof MouseWheelEvent) { JScrollBar toScroll = getVerticalScrollBar(); if (toScroll == null || !toScroll.isVisible()) { ((MouseWheelEvent) e).consume(); return; } } super.processEvent(e); } }; sp.setHorizontalScrollBar(null); return sp; } // ... }} - 上記の方法では、ドロップダウンリスト内では閉じなくなるが、ドロップダウンリスト外でホイールを回転するとポップアップが閉じてしまう。`Toolkit.getDefaultToolkit().addAWTEventListener(...)`でもうまくいかない。 -- &user(aterai); &new{2012-04-24 (火) 20:07:13}; - [https://bugs.openjdk.java.net/browse/JDK-8033069 JDK-8033069 mouse wheel scroll closes combobox popup - Java Bug System]で、ホイール回転の方は修正され%%る予定(`Java 9`)%%、`JDK 8`にも[https://bugs.openjdk.java.net/browse/JDK-8078391 バックポート]された。 -- &user(aterai); &new{2015-05-07 (木) 15:59:53}; #comment