2

此处提出了一个非常相似的问题,虽然我承认这一点,但问题的解决方案并不能完全解决我的问题。A JList,当单击时,将选择最接近鼠标单击的索引列表项。AJList也将为每次单击+拖动事件触发执行此操作。

JList当单击+拖动位置在可见列表之外时,我想阻止我在单击+拖动事件期间选择项目。我该怎么办?

我曾考虑覆盖另一种方法,该方法涉及选择列表项的单击+拖动事件。我想试试这个setSelectionInterval()方法。

JList<String list = new JList<String>(){
        private static final long serialVersionUID = 1L;
        @Override
        public int locationToIndex(Point location) {
            int index = super.locationToIndex(location);
            if (index != -1 && !getCellBounds(index, index).contains(location)) {
                clearSelection();
                return -1;
                //an excellent click-only solution to prohibit the selecting of 
                //items from beyond the visible list
            }
            else {
                return index;
            }
        }
        @Override
        public void setSelectionInterval(int anchor, int lead) {
            super.setSelectionInterval(anchor, lead);
            System.out.println("setSelectionInterval");
        }           
    };

我发现每次单击+拖动显示的任意位置时JList,都会收到我添加到上述方法中的 System.out 消息“setSelectionInterval”。就覆盖方法而言,我不知道从哪里开始。也许这不是我应该处理的方式。在源代码中,setSelectionInterval()我迷路了,试图找到任何涉及的侦听器的方法,所以我来到了这里。:p

我非常感谢任何指向我应该寻找的地方或完全解决方案的指针。提前致谢!

这是一个与我的设置方式接近的 SSCCE 示例。实际上,当从列表项本身触发仅单击事件时,列表不会选择项目。当单击+拖动事件从列表项中触发时,我希望发生同样的效果。

import java.awt.BorderLayout;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;



public class TestMain {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel content = new JPanel(new BorderLayout());

        String[] data = {"Luke", "Jeff", "Bryce"};
        JList<String> list = new JList<String>(data){
            private static final long serialVersionUID = 1L;

            @Override
            public int locationToIndex(Point location) {
                System.out.println("location to index");
                int index = super.locationToIndex(location);
                if (index != -1 && !getCellBounds(index, index).contains(location)) {
                    clearSelection();
                    return -1;
                }
                else {
                    return index;
                }
            }
        }

        content.add(list, BorderLayout.CENTER);
        frame.setContentPane(content);
        frame.setSize(200,200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}
4

2 回答 2

3

如果禁用整个拖动功能是可以接受的,那么以下应该会有所帮助:

@Override
protected void processMouseMotionEvent(MouseEvent e) {
    if(MouseEvent.MOUSE_DRAGGED != e.getID()) {
        super.processMouseMotionEvent(e);
    }
}
于 2014-05-29T12:53:46.273 回答
2

当单击+拖动位置在可见列表之外时,我想防止我的 JList 在单击+拖动事件期间选择项目。

不确定我是否理解要求。让我们从选择的第一行开始。

如果单击第一行,然后继续拖动到第二行,则第二行将突出显示。继续拖动,第三行将突出显示。继续拖过第三行,你想发生什么?

您是说您希望选择第一行,因为那是您开始的地方?如果这是您要问的,那么您需要查看 BasicListUI。这是将鼠标侦听器添加到 JList 的位置。您将需要以某种方式处理 mousePressed 事件以保存当前选定的行。然后,当您开始拖到最后一行之外时,您将需要以某种方式覆盖 mouseDragged 代码的默认行为以重置所选行。

我不知道该怎么做。

我收到了我添加到上述方法中的“setSelectionInterval”的 System.out 消息

试图覆盖该方法中的代码为时已晚。当您拖动鼠标时,选择将继续更新。您不知道是否正在调用此方法,因为鼠标确实位于最后一行或超过最后一行,因为您无权访问鼠标点。

我想您可以尝试使用 MouseInfo 类来确定调用此方法时鼠标的位置,但不知何故,您仍然需要知道拖动最初是在选择第一行时开始的。我也不知道该怎么做。

于 2013-04-20T05:07:26.647 回答