Java JList-locationToIndex()始终为线程中的鼠标位置返回相同的索引

Java JList-locationToIndex()始终为线程中的鼠标位置返回相同的索引,java,multithreading,swing,jlist,point,Java,Multithreading,Swing,Jlist,Point,我正在用JLists进行测试,我想在MouseEnter上弹出一个小窗口,显示鼠标悬停在上面的列表项的内容;同时,该窗口在MouseExit上进行处理。 到目前为止,这工作得很好,但要更新它,鼠标必须退出并重新进入 现在我想让它在并行线程中工作,并一直更新窗口,这样它就可以在不必先退出的情况下进行更改,并尝试了以下方法: public void run() { while (!Thread.interrupted()) { Poi

我正在用JLists进行测试,我想在MouseEnter上弹出一个小窗口,显示鼠标悬停在上面的列表项的内容;同时,该窗口在MouseExit上进行处理。
到目前为止,这工作得很好,但要更新它,鼠标必须退出并重新进入

现在我想让它在并行线程中工作,并一直更新窗口,这样它就可以在不必先退出的情况下进行更改,并尝试了以下方法:

     public void run() {
            while (!Thread.interrupted()) {
                Point p = MouseInfo.getPointerInfo().getLocation();
                String text = list.getModel().getElementAt(
                        list.locationToIndex(p));
                lab.setText(text);
            }
但无论鼠标在何处,它始终只显示列表中最后一项的内容。
如果我打印出
文本
它总是相同的内容,即使鼠标位置改变


我做错了什么?

MouseInfo.getPointerInfo().getLocation()
给出了鼠标在屏幕上下文中的位置

JList#locationToIndex
希望该点位于
JList
的上下文中

这一点一开始可能有点让人困惑,但是,基本上,在处理类似这样的功能时,除了要在其坐标上下文中的点之外,其他组件都会出现问题,其中0x0是组件的左上角。这实际上让生活变得容易多了,因为你不需要经常在屏幕和组件坐标之间转换

SwingUtilities.convertPointFromScreen(p, list);
您需要首先将
转换为组件坐标

SwingUtilities.convertPointFromScreen(p, list);
然后请求由点表示的索引

还要注意,Swing不是线程安全的,这意味着您只能从事件调度线程的上下文中访问或修改UI组件

所以这使得

String text = list.getModel().getElementAt(
                    list.locationToIndex(p));
lab.setText(text);
…非常危险

有关更多详细信息,请参阅

不知道你到底想做什么,很难提供其他建议,但是你可以考虑使用A和/或,注册到<代码> JLIST/COD>,而不是


这样做的直接好处是,
MouseEvent
已经转换为触发事件的组件的坐标空间

MouseInfo.getPointerInfo().getLocation()
给出了鼠标在屏幕上下文中的位置

JList#locationToIndex
希望该点位于
JList
的上下文中

这一点一开始可能有点让人困惑,但是,基本上,在处理类似这样的功能时,除了要在其坐标上下文中的点之外,其他组件都会出现问题,其中0x0是组件的左上角。这实际上让生活变得容易多了,因为你不需要经常在屏幕和组件坐标之间转换

SwingUtilities.convertPointFromScreen(p, list);
您需要首先将
转换为组件坐标

SwingUtilities.convertPointFromScreen(p, list);
然后请求由点表示的索引

还要注意,Swing不是线程安全的,这意味着您只能从事件调度线程的上下文中访问或修改UI组件

所以这使得

String text = list.getModel().getElementAt(
                    list.locationToIndex(p));
lab.setText(text);
…非常危险

有关更多详细信息,请参阅

不知道你到底想做什么,很难提供其他建议,但是你可以考虑使用A和/或,注册到<代码> JLIST/COD>,而不是


这样做的直接好处是,
MouseEvent
已经转换为触发事件的组件的坐标空间

使用此代码而不是您的代码

        Point p = MouseInfo.getPointerInfo().getLocation();
        list.setSelectedIndex(list.locationToIndex(p));

        String text = list.getSelectedValue().toString();
        lab.setText(text);

使用此代码代替您的代码

        Point p = MouseInfo.getPointerInfo().getLocation();
        list.setSelectedIndex(list.locationToIndex(p));

        String text = list.getSelectedValue().toString();
        lab.setText(text);

另一个快速的问题,你能给我什么建议让窗口随着鼠标的位置动态地改变它的位置,这样它就不会停留在它第一次出现的位置?使用window.setLocation(p)会使它很快出现和消失,看起来不太好,有什么好办法吗?老实说,最好的解决办法是
setLocation
问题是,你想做什么+1使用ListSelectionListener而不是MouseWhather,但HightLigger可以这样工作,也许在谈论渲染器的概念时,另一个简单的问题是,你能给我什么建议,让窗口随着鼠标的位置动态地改变它的位置,这样它就不会停留在最初出现的位置?使用window.setLocation(p)会使它很快出现和消失,看起来不太好,有什么好办法吗?老实说,最好的解决办法是
setLocation
问题是,你想做什么+1使用ListSelectionListener而不是MouseWhather,但HightLigger可以这样工作,也许谈论渲染器概念
e
来自哪里?
e
来自哪里?欢迎来到堆栈溢出!虽然这段代码片段可能是解决方案,但包含解释确实有助于提高文章的质量。请记住,您将在将来回答读者的问题,而这些人可能不知道您的代码建议的原因。欢迎使用堆栈溢出!虽然这段代码片段可能是解决方案,但包含解释确实有助于提高文章的质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。