async
async

Reputation: 1537

Java (Swing): MouseMoved not working at all

This is driving me nuts. It must be an extremely simple problem, but I can't possibly see it.

Basically mouseMoved is NEVER called. Below is the code.

public class MouseMotionThing {
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            JFrame jFrame = new JFrame();
            jFrame.setContentPane(new ContentPane());
            jFrame.setSize(400, 400);
            jFrame.setVisible(true);
            jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }); 
}
}

And my panel. This implementation uses a MouseInputListener:

class ContentPane extends JPanel implements MouseInputListener {
int x = 0, y = 0;

public ContentPane() {
    setOpaque(true);
    addMouseListener(this);
    addMouseMotionListener(this);

}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    g.drawLine(0, 0, x, y);
}

@Override
public void mouseDragged(MouseEvent e) {
    System.out.println("Mouse Dragged!");
}

@Override
public void mouseMoved(MouseEvent e) {
    System.out.println("CALLED MOUSE MOVED");
    x = e.getX();
    y = e.getY();

    repaint();
}

@Override
public void mouseClicked(MouseEvent e) {
}

@Override
public void mousePressed(MouseEvent e) {
}

@Override
public void mouseReleased(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}
}

whereas this alternative implementation uses only a MouseMotionListener:

class ContentPane extends JPanel implements MouseMotionListener {
int x = 0, y = 0;

public ContentPane() {
    setOpaque(true);
    addMouseMotionListener(this);

}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    g.drawLine(0, 0, x, y);
}

@Override
public void mouseDragged(MouseEvent e) {
    System.out.println("Mouse Dragged!");
}

@Override
public void mouseMoved(MouseEvent e) {
    System.out.println("CALLED MOUSE MOVED");
    x = e.getX();
    y = e.getY();

    repaint();
}
}

In none of the above alternative implementations is mouseMoved EVER called. I'm adding the right listeners every single time, but it's simply not working. mouseDragged works fine though. What am I missing?

LE: I tested the code on Ubuntu 12.10 & JDK 7, worked fine. Then when I went back to my W8 machine, it started working. I did absolutely nothing more than restart my laptop. I couldn't reproduce the problem nor track it down, but I will come back if I get it again and manage to find something.

Upvotes: 3

Views: 4807

Answers (3)

Jake Hicks
Jake Hicks

Reputation: 21

I happened to come across a similar issue in one of the applications I contribute to. I couldn't find anything else that pointed to the root cause, so I started doing some Java AWT logging as illustrated on Oracle's Logging Overview page.

After analyzing parts of the file, I found that there were 5 mouse buttons being registered to the JVM:

<record>
    <date>2015-06-18T15:45:54</date>
    <millis>1434656754395</millis>
    <sequence>70</sequence>
    <logger>sun.awt.windows.WDesktopProperties</logger>
    <level>FINE</level>
    <class>sun.awt.windows.WDesktopProperties</class>
    <method>setIntegerProperty</method>
    <thread>1</thread>
    <message>awt.mouse.numButtons=5</message>
</record>

I also realized that other mouse events (MOUSE_ENTERED, MOUSE_EXITED, MOUSE_DRAGGED) had a extModifiers value of Button5, which is weird because I was just using a touch pad and no other button is pressed. I'm not sure if this would prevent the MOUSE_MOVED event from being fired - I'm guessing this would take some research into lower level Java.

<record>
    <date>2015-06-18T15:45:55</date>
    <millis>1434656755026</millis>
    <sequence>329</sequence>
    <logger>java.awt.event.EventDispatchThread</logger>
    <level>FINEST</level>
    <class>java.awt.EventDispatchThread</class>
    <method>pumpOneEventForFilters</method>
    <thread>13</thread>
    <message>Dispatching: java.awt.event.MouseEvent[MOUSE_ENTERED,(388,387),absolute(388,387),button=0,extModifiers=Button5,clickCount=0] on frame0</message>
</record>

I did some research on extra mouse buttons and found another Oracle page talking about Desktop Properties. I changed the startup parameters of Java to include -Dsun.awt.enableExtraMouseButtons=false, and voila, my application started working again.

I tested a very simple Java application with listening to MOUSE_MOVED on a variety of Windows JRE's, and they all exhibited the same issue when not setting this parameter.

If extra mouse buttons aren't going to be used in your application, then this may be a workaround for you.

Upvotes: 1

async
async

Reputation: 1537

Well, it seemed that I had those problems when I used my A4TECH G10-770F mouse on Windows 8. If I turned it off, things went back to normal. I didn't look into it in greater detail though - I already had another mouse and used that one instead.

Upvotes: 0

trashgod
trashgod

Reputation: 205785

It's not clear where things may have gone awry; it may help to do a full build. For reference, I've re-factored your sscce to use a MouseAdapter and remove a leaking this from the JPanel.

import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class MouseMotionThing {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame jFrame = new JFrame();
                jFrame.add(new MousePanel());
                jFrame.pack();
                jFrame.setSize(400, 400);
                jFrame.setVisible(true);
                jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }

    private static class MousePanel extends JPanel {

        Point p = new Point();

        public MousePanel() {
            setOpaque(true);
            addMouseMotionListener(new MouseHandler());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawLine(0, 0, p.x, p.y);
        }

        private class MouseHandler extends MouseAdapter {

            @Override
            public void mouseDragged(MouseEvent e) {
                update(e);
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                update(e);
            }

            private void update(MouseEvent e) {
                System.out.println(e.paramString());
                MousePanel.this.p = e.getPoint();
                MousePanel.this.repaint();
            }
        }
    }
}

Upvotes: 2

Related Questions