【问题标题】:Java (Swing): MouseMoved not working at allJava(Swing):MouseMoved 根本不工作
【发布时间】:2015-06-19 05:11:50
【问题描述】:

这让我发疯了。这一定是一个非常简单的问题,但我不可能看到它。

基本上 mouseMoved 永远不会被调用。下面是代码。

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);
        }
    }); 
}
}

还有我的面板。此实现使用 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) {
}
}

而此替代实现仅使用 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();
}
}

在上述替代实现中,都没有调用 mouseMoved。我每次都在添加正确的听众,但它根本不起作用。 mouseDragged 工作正常。我错过了什么?

LE:我在 Ubuntu 12.10 和 JDK 7 上测试了代码,运行良好。然后当我回到我的 W8 机器时,它开始工作了。我只是重新启动笔记本电脑。我无法重现该问题,也无法追踪它,但如果我再次遇到它并设法找到一些东西,我会回来的。

【问题讨论】:

  • ContentPane 都适合我。
  • 是的,也为我工作!您的代码看起来也不错。
  • 你的 JFrame 有焦点吗?也许尝试点击面板然后在上面移动
  • @drewmore4:没关系。只要鼠标悬停在 GUI 上并且 GUI 上没有其他任何东西在窃取鼠标侦听器(例如活动的玻璃窗格),那么代码就可以工作。
  • sscce+1。

标签: java swing mouselistener


【解决方案1】:

目前还不清楚哪里出了差错;进行完整构建可能会有所帮助。作为参考,我已将您的 sscce 重构为使用 MouseAdapter 并从 JPanel 中删除泄漏的 this

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();
            }
        }
    }
}

【讨论】:

  • 谢谢。代码看起来(并且)非常好,但我仍然有相同的行为:拖动有效,但从未调用过 mouseMoved。
  • 路径中有一个陈旧类的环。这就是我使用嵌套和重命名类的部分原因。构建环境有什么帮助吗?
  • 在 Windows 7 / JDK 7 上测试正常。
【解决方案2】:

我碰巧在我参与的一个应用程序中遇到了类似的问题。我找不到任何其他指向根本原因的东西,所以我开始做一些 Java AWT 日志记录,如 Oracle 的 Logging Overview 页面所示。​​

分析部分文件后,我发现有 5 个鼠标按钮被注册到 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>

我还意识到其他鼠标事件(MOUSE_ENTEREDMOUSE_EXITEDMOUSE_DRAGGED)的extModifiers 值为Button5,这很奇怪,因为我只是使用触摸板而没有其他按钮按下。我不确定这是否会阻止 MOUSE_MOVED 事件被触发 - 我猜这需要对较低级别的 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>

我对额外的鼠标按钮进行了一些研究,发现另一个 Oracle 页面在谈论 Desktop Properties。我将 Java 的启动参数更改为包含 -Dsun.awt.enableExtraMouseButtons=false,瞧,我的应用程序又开始工作了。

我测试了一个非常简单的 Java 应用程序,在各种 Windows JRE 上监听 MOUSE_MOVED,当不设置此参数时,它们都出现了同样的问题。

如果您的应用程序中不会使用额外的鼠标按钮,那么这可能是您的解决方法。

【讨论】:

    【解决方案3】:

    嗯,我在 Windows 8 上使用 A4TECH G10-770F 鼠标时似乎遇到了这些问题。如果我将其关闭,一切都会恢复正常。不过,我并没有更详细地研究它——我已经有了另一只鼠标,而是使用了那个。

    【讨论】:

    • 太糟糕了,我的触摸板发生了这种情况
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 2012-01-08
    • 1970-01-01
    • 2020-07-31
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多