Question

I'm testing around a bit with JLists and I wanted a little window to pop up on MouseEnter and show the content of the list entry the mouse was hovering over; also the window disposes on MouseExit.
So far this worked great, but for it to update the mouse has to exit and re-enter.

Now I wanted to make it work in a parallel Thread and update the window all the time, so it would change without me having to exit first, and tried this:

     public void run() {
            while (!Thread.interrupted()) {
                Point p = MouseInfo.getPointerInfo().getLocation();
                String text = list.getModel().getElementAt(
                        list.locationToIndex(p));
                lab.setText(text);
            }

But it always only shows the content of the last entry in the list, no matter where the mouse is.
If I print out textit's always the same content, even though the mouse position changes.

What am I doing wrong?

Was it helpful?

Solution

MouseInfo.getPointerInfo().getLocation() gives the location of the mouse within the context of the screen.

JList#locationToIndex expects the point to be within the context of the JList.

This can be a little confusing at first, but, basically, when dealing with functionality like this, components except the point to be within their coordinate context, where 0x0 is the top, left corner of the component. This actually makes life a lot easier, as you don't constantly need to be translating between screen and component coordinates...

You will need to first convert the Point to component coordinates...

SwingUtilities.convertPointFromScreen(p, list);

Then request the index of represented by the point

Also note that Swing is not thread safe, that means that you should only ever access or modify UI components from within the context of the Event Dispatching Thread.

So this makes...

String text = list.getModel().getElementAt(
                    list.locationToIndex(p));
lab.setText(text);

...very dangerous.

See Concurrency in Swing for more details

Without knowning exactly what you're trying to do it's difficult to provide alternative suggestions, but you might consider using a MouseListener and/or MouseMotionListener, registered to the JList, instead

The immediate benefit of this is that the MouseEvent is already converted to the coordinate space of the component that triggered the event

OTHER TIPS

Use this code instead yours code

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

        String text = list.getSelectedValue().toString();
        lab.setText(text);
private void JLISTE_clicked(java.awt.event.MouseEvent evt) {                                        
    if (SwingUtilities.isRightMouseButton(evt)){
        if (evt.getComponent()==JLISTE){
            int idx = JLISTE.locationToIndex(evt.getPoint());
            System.out.println("Index rightclicked : " + idx); // testing
            JLISTE.setSelectedIndex(idx);
        }
    }
....
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top