12

JList で選択されたインデックスがクリックされた場合、選択を解除したい。つまり、インデックスをクリックすると、実際に選択が切り替わります。これがサポートされているようには見えなかったので、試してみました

list.addMouseListener(new MouseAdapter()
{
   public void mousePressed(MouseEvent evt)
   {
      java.awt.Point point = evt.getPoint();
      int index = list.locationToIndex(point);
      if (list.isSelectedIndex(index))
         list.removeSelectionInterval(index, index);
   }
});

ここでの問題は、 JList が既にマウス イベントに作用した後にこれが呼び出されているため、すべての選択が解除されることです。そこで、JList の MouseListeners をすべて削除し、独自の MouseListeners を追加してから、デフォルトのリスナーをすべて追加し直しました。JList は、インデックスの選択を解除した後でインデックスを再選択するため、うまくいきませんでした。とにかく、最終的に思いついたのは

MouseListener[] mls = list.getMouseListeners();
for (MouseListener ml : mls)
   list.removeMouseListener(ml);
list.addMouseListener(new MouseAdapter()
{
   public void mousePressed(MouseEvent evt)
   {
      java.awt.Point point = evt.getPoint();
      final int index = list.locationToIndex(point);
      if (list.isSelectedIndex(index))
         SwingUtilities.invokeLater(new Runnable()
         {
            public void run()
            {
               list.removeSelectionInterval(index, index);
            }
         });
   }
});
for (MouseListener ml : mls)
   list.addMouseListener(ml);

...そしてそれはうまくいきます。しかし、私はそれが好きではありません。より良い方法はありますか?

4

6 に答える 6

12

「ListSelectionModel: トグル選択モードの有効化」の例を参照してください: http://java.sun.com/products/jfc/tsc/tech_topics/jlist_1/jlist.html

複数選択リスト ボックス用に少し変更し (setSelectionInterval を addSelectionInterval に変更)、クリックして選択を解除し、マウスがダウンしているときにマウスを移動した場合の再選択の問題を解消しました (追加と追加の両方のジェスチャー開始チェックを移動しました)。削除する)。

objList.setSelectionModel(new DefaultListSelectionModel() {
    private static final long serialVersionUID = 1L;

    boolean gestureStarted = false;

    @Override
    public void setSelectionInterval(int index0, int index1) {
        if(!gestureStarted){
            if (isSelectedIndex(index0)) {
                super.removeSelectionInterval(index0, index1);
            } else {
                super.addSelectionInterval(index0, index1);
            }
        }
        gestureStarted = true;
    }

    @Override
    public void setValueIsAdjusting(boolean isAdjusting) {
        if (isAdjusting == false) {
            gestureStarted = false;
        }
    }

});
于 2012-02-08T15:36:45.707 に答える
5

これはどう?

import javax.swing.DefaultListSelectionModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.ListSelectionModel;

public class A {
    public static void main(String[] args) {
        JFrame f = new JFrame("Test");
        final JList list = new JList(new String[] {"one","two","three","four"});
        list.setSelectionModel(new DefaultListSelectionModel(){


            @Override
            public void setSelectionInterval(int index0, int index1) {
                if (index0==index1) {
                    if (isSelectedIndex(index0)) {
                        removeSelectionInterval(index0, index0);
                        return;
                    }
                }
                super.setSelectionInterval(index0, index1);
            }

            @Override
            public void addSelectionInterval(int index0, int index1) {
                if (index0==index1) {
                    if (isSelectedIndex(index0)) {
                        removeSelectionInterval(index0, index0);
                        return;
                    }
                super.addSelectionInterval(index0, index1);
                }
            }

        });
        f.getContentPane().add(list);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }

}

それは機能しますが、1つの副作用に注意してください...たとえば、次のようにモードを複数選択に設定した場合:

list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION );

マウスドラッグで複数のオブジェクトを選択することはできません。Ctrl (または Shift) クリックが機能します。修正できると確信していますが、単一選択リストについてこれを求めたと思います...質問を変更しない場合は、複数選択問題の解決策を考え始めることができます。

于 2010-03-28T01:50:18.090 に答える
3

この質問にはすでに受け入れられた答えがあることは知っていますが、私はこのタスクに数時間立ち往生してしまったので、少し拡大すると思いました。

選択したアイテムに対してクリックして選択解除するア​​クションを実装しようとしましたが、リストの実装では、次のように指定された単一選択モードを使用する必要があります。

JList jlist = new JList(new DefaultListModel());
jlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

残念ながら、これにより、上記のFuryComptuersによるこの回答を含め、多くのSO質問でクリックして選択を解除する問題の多くのソリューションに対する例外と冗長な呼び出しが発生しました。のコード、特にメソッドを呼び出すandメソッドが原因で、(明らかに)例外につながる循環呼び出しが発生しました。この「問題のある」コードを以下に示します。DefaultListSelectionModel.classaddSelectionInterval(int index0, int index1)removeSelectionInterval(int index0, int index1)setSelectionInterval(int index0, int index1)

 // If we only allow a single selection, channel through
    // setSelectionInterval() to enforce the rule.
    if (getSelectionMode() == SINGLE_SELECTION) {
        setSelectionInterval(index0, index1);
        return;
    }

Sawas Dalkitsis回答はこの問題を解決しましたが、選択したアイテム上でマウスをドラッグすると、それでも奇妙な動作をします(選択したアイテムは、マウスをドラッグしている間、何度も選択および選択解除されます)。これは問題のようには思えませんが、(どうやら)私は手が震え、クリック中にマウスを少し動かすと、望ましくない動作が発生しました。Sawas Dalkitsisの 回答FuryComptuers回答を組み合わせて、次のコードを取得しました。これは、希望どおりに機能しているようです。

    JList jlist = new JList(new DefaultListModel());
    jList.setSelectionModel(new DefaultListSelectionModel() {
        private static final long serialVersionUID = 1L;

        boolean gestureStarted = false;

        @Override
        public void setSelectionInterval(int index0, int index1) {
            if(!gestureStarted){
            if (index0==index1) {
                if (isSelectedIndex(index0)) {
                    removeSelectionInterval(index0, index0);
                    return;
                }
            }
            super.setSelectionInterval(index0, index1);
            }
            gestureStarted = true;
        }

        @Override
        public void addSelectionInterval(int index0, int index1) {
            if (index0==index1) {
                if (isSelectedIndex(index0)) {
                    removeSelectionInterval(index0, index0);
                    return;
                }
            super.addSelectionInterval(index0, index1);
            }
        }

        @Override
        public void setValueIsAdjusting(boolean isAdjusting) {
            if (isAdjusting == false) {
                gestureStarted = false;
            }
        }

    });
    jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

注:Sawas DalkitsisListSelectionModel.SINGLE_INTERVAL_SELECTIONのように、これをチェックしなかったので、その場合に実装する場合は注意が必要です。

于 2012-12-10T19:30:33.953 に答える
0

クリックされたポイントを解読して選択したアイテムに変換する代わりに、いつでもListSelectionListenerを使用できます。

http://java.sun.com/docs/books/tutorial/uiswing/examples/events/index.html#ListSelectionDemo

http://java.sun.com/docs/books/tutorial/uiswing/events/listselectionlistener.html

http://java.sun.com/docs/books/tutorial/uiswing/examples/events/ListSelectionDemoProject/src/events/ListSelectionDemo.java

上記のJavaファイルのリンクには、「選択解除」を行うために簡単に改善できる実装があります:)

于 2010-03-27T13:33:54.803 に答える
0

複数選択をサポートするようにFuryComptuers の回答を拡張し、setSelectionInterval直接呼び出された場合に機能しない問題を修正しました。

public class ToggleableListSelectionModel extends DefaultListSelectionModel {
    private static final long serialVersionUID = 1L;

    private boolean mGestureStarted;

    @Override
    public void setSelectionInterval(int index0, int index1) {
        // Toggle only one element while the user is dragging the mouse
        if (!mGestureStarted) {
            if (isSelectedIndex(index0)) {
                super.removeSelectionInterval(index0, index1);
            } else {
                if (getSelectionMode() == SINGLE_SELECTION) {
                    super.setSelectionInterval(index0, index1);
                } else {
                    super.addSelectionInterval(index0, index1);
                }
            }
        }

        // Disable toggling till the adjusting is over, or keep it
        // enabled in case setSelectionInterval was called directly.
        mGestureStarted = getValueIsAdjusting();
    }

    @Override
    public void setValueIsAdjusting(boolean isAdjusting) {
        super.setValueIsAdjusting(isAdjusting);

        if (isAdjusting == false) {
            // Enable toggling
            mGestureStarted = false;
        }
    }   
}
于 2014-05-09T13:23:46.137 に答える
0

を押しながらマウスクリックを使用して複数のアイテムを一度に選択すると、Nick Dandoulakisの答えShiftはうまくいきませんでした。

またはでマウスクリックを使用してアイテムを選択すると、次のListSelectionModelように動作します。ShiftCtrl

また、Shift + Ctrlどちらかを長押しすると、→</kbd> or ←</kbd> selects items the way I want it to.

public static class ToggleableListSelectionModel extends DefaultListSelectionModel {
        private static final long serialVersionUID = 1L;

        @Override
        public void setSelectionInterval(int startIndex, int endIndex) {
            if (startIndex == endIndex) {
                if (multipleItemsAreCurrentlySelected()) {
                    clearSelection();
                }
                if (isSelectedIndex(startIndex)) {
                    clearSelection();
                }
                else {
                    super.setSelectionInterval(startIndex, endIndex);
                }
            }
            // User selected multiple items
            else {
                super.setSelectionInterval(startIndex, endIndex);
            }
        }

        private boolean multipleItemsCurrentlyAreSelected() {
            return getMinSelectionIndex() != getMaxSelectionIndex();
        }
    }
于 2015-07-10T08:49:32.053 に答える