TITLE:JListをマウスクリックのみで複数選択する
Posted by at 2011-07-18

JListをマウスクリックのみで複数選択する

JListをアイテムをマウスクリックだけで複数選択できるように設定します。
  • category: swing folder: ListMouseSelection title: JListをマウスクリックのみで複数選択する tags: [JList, MouseListener] author: aterai pubdate: 2011-07-18T17:21:18+09:00 description: JListをアイテムをマウスクリックだけで複数選択できるように設定します。 image: https://lh6.googleusercontent.com/-wj2xm8BlBbA/TiPrjr1sQ5I/AAAAAAAAA_c/NiXO891B5fs/s800/ListMouseSelection.png hreflang:
       href: https://java-swing-tips.blogspot.com/2012/04/select-multiple-items-in-jlist-by.html
       lang: en

概要

JListをアイテムをマウスクリックだけで複数選択できるように設定します。
ListMouseSelection.png

サンプルコード

#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
JList list = new JList(model) {
  private ClearSelectionListener listener;
  @Override public void setSelectionInterval(int anchor, int lead) {
    if(anchor==lead && lead>=0 && anchor>=0) {
      if(listener.isDragging) {
    if (anchor == lead && lead >= 0 && anchor >= 0) {
      if (listener.isDragging) {
        addSelectionInterval(anchor, anchor);
      }else if(!listener.isInCellDragging) {
        if(isSelectedIndex(anchor)) {
      } else if (!listener.isInCellDragging) {
        if (isSelectedIndex(anchor)) {
          removeSelectionInterval(anchor, anchor);
        }else{
        } else {
          addSelectionInterval(anchor, anchor);
        }
        listener.isInCellDragging = true;
      }
    }else{
    } else {
      super.setSelectionInterval(anchor, lead);
    }
  }
};

解説

  • 左: Default
  • 中: MouseEvent
    • JList#processMouseEvent, JList#processMouseMotionEventをオーバーライドして、常にCtrlキーが押されている状態にする
    • マウスでアイテムをドラッグしても選択状態は変わらない
    • JListの空白部分をクリックした場合、アイテムの選択状態は変更せず(MouseEvent#consume())、フォーカスだけJListに移動
    • 参考: Thread: JList where mouse click acts like ctrl-mouse click

解説

  • 左: Default
    • Ctrlキーを押しながらマウスクリックでリストアイテムの複数選択が可能
  • 中: MouseEvent
    • JList#processMouseEventJList#processMouseMotionEventをオーバーライドして常にCtrlキーが押されている状態に設定
    • マウスでアイテムをドラッグしても選択状態は変化しない
    • JListの空白部分をクリックした場合、アイテムの選択状態は変更せず(MouseEvent#consume())フォーカスだけJListに移動
    • 参考: Swing - JList where mouse click acts like ctrl-mouse click
      JList list = new JList(model) {
        @Override protected void processMouseMotionEvent(MouseEvent e) {
          super.processMouseMotionEvent(convertMouseEvent(e));
        }
      #spanadd
      
      #spanend
        @Override protected void processMouseEvent(MouseEvent e) {
          if(e.getID()==MouseEvent.MOUSE_PRESSED && 
             !getCellBounds(0, getModel().getSize()-1).contains(e.getPoint())) {
          if (e.getID() == MouseEvent.MOUSE_PRESSED &&
              !getCellBounds(0, getModel().getSize() - 1).contains(e.getPoint())) {
            e.consume();
            requestFocusInWindow();
          }else{
          } else {
            super.processMouseEvent(convertMouseEvent(e));
          }
        }
      #spanadd
      
      #spanend
        private MouseEvent convertMouseEvent(MouseEvent e) {
          //Thread: JList where mouse click acts like ctrl-mouse click
          //http://forums.oracle.com/forums/thread.jspa?messageID=5692411
          // Swing - JList where mouse click acts like ctrl-mouse click
          // https://community.oracle.com/thread/1351452
          return new MouseEvent(
            (Component) e.getSource(),
            e.getID(), e.getWhen(),
            //e.getModifiers() | InputEvent.CTRL_MASK,
            //select multiple objects in OS X: Command+click
            //pointed out by nsby
            e.getModifiers() | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(),
            e.getX(), e.getY(),
            e.getXOnScreen(), e.getYOnScreen(),
            e.getClickCount(),
            e.isPopupTrigger(),
            e.getButton());
              (Component) e.getSource(),
              e.getID(), e.getWhen(),
              // e.getModifiers() | InputEvent.CTRL_MASK,
              // select multiple objects in OS X: Command+click
              // pointed out by nsby
              e.getModifiers() | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(),
              e.getX(), e.getY(),
              e.getXOnScreen(), e.getYOnScreen(),
              e.getClickCount(),
              e.isPopupTrigger(),
              e.getButton());
        }
      };
      
  • 右: SelectionInterval
    • JList#setSelectionIntervalをオーバーライドして、ひとつのアイテムのセルを選択した場合は、JList#addSelectionInterval、JList#removeSelectionIntervalを使用するように変更
    • マウスでアイテムをドラッグすると、選択状態になる
  • 右: SelectionInterval

参考リンク

参考リンク

コメント

  • OSX(snow leopard)では、MouseEventは複数選択が出来ません。キーボードを使っても(command+クリック)無理でした。 -- nsby
    • ご指摘ありがとうございます。OSXでは「command+クリック」で複数選択でしたっけ? InputEvent.CTRL_MASK決め打ちではなく、Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()に修正した方がいいのかもしれません(ソースなどを更新しましたが、正常に動作するかは確認していません…)。 -- aterai
  • Web Startでもう一度実行してみましたが、やはり出来ませんでした。MouseEventで複数選択ha -- nsby
  • あ、変な所で切れてしまいました。すみません。あらためて、MouseEventで複数選択出来るのは、Shift+クリックで選択した場合のみです。それ意外はダメでした。(Cntl+クリックとかでもダメ) -- nsby
    • Web Startのキャッシュは、…関係なさそうですね。src.zipをダウンロードしてJList#processMouseEvent(...)内で、System.out.println(e);したりsuper.processMouseEvent(convertMouseEvent(e));だけにしてみるとどうなるでしょうか? -- aterai
  • MouseEvent eを出力してみました。ちゃんと処理してるように見えるんですが・・・

コメント