【问题标题】:Stackoverflow error when trying to dispatch MouseEvents. mouseMoved works but mouseDragged does not尝试调度 MouseEvents 时出现 Stackoverflow 错误。 mouseMoved 有效,但 mouseDragged 无效
【发布时间】:2013-06-28 02:28:02
【问题描述】:

我一直在尝试实现鼠标运动事件调度,但我仍然收到堆栈溢出错误。它适用于 mouseMoved(MouseEvent e) 方法,但不适用于 mouseDragged(MouseEvent e)。有人知道为什么吗?有什么解决办法吗?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame {

public Test() { 
    setLayout(null);
    setSize(500,500);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    addMouseMotionListener(new MouseMotionListener() {
         public void mouseMoved(MouseEvent e) {
             System.err.println("moved outside");
         }
         public void mouseDragged(MouseEvent e) {
            System.err.println("dragged outside");
         }
    });

    JPanel inside = new JPanel();
    inside.setLocation(0, 0);
    inside.setSize(100, 100);
    inside.setBackground(Color.RED);

    inside.addMouseMotionListener(new MouseMotionListener() {
        public void mouseDragged(MouseEvent e) {
            System.out.println("dragged inside");

            //The error occurs here when I begin dragging 
            //here and continue dragging to any other location.

            Test.this.dispatchEvent(e);
        }
        public void mouseMoved(MouseEvent e) {
            System.out.println("moved inside");
            Test.this.dispatchEvent(e);
        }
    });
    add(inside);
}

public static void main(String[] args) {
    Test client = new Test();
}
}

我的实际项目使用了许多内部组件,我的目标是让每个组件实现自己的鼠标按下/单击/释放操作,并让框架处理影响所有组件的鼠标运动和拖动。

这是一个类似的代码,它适用于两种鼠标移动方法。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test2 {

public static void main(String... args) {
    SwingUtilities.invokeLater(new Runnable() {

        public void run() {
            final JComponent outside = new JPanel();
            JComponent inside = new JPanel();
            inside.setBackground(Color.red);
            inside.setPreferredSize(new Dimension(200, 200));
            inside.addMouseMotionListener(new MouseAdapter() {
                public void mouseDragged(MouseEvent e) {
                    System.out.println("dragged inside");
                    outside.dispatchEvent(e);
                }
                public void mouseMoved(MouseEvent e) {
                    System.out.println("moved inside");
                    outside.dispatchEvent(e);
                }
            });

            outside.add(inside);
            outside.setPreferredSize(new Dimension(300, 300));
            outside.addMouseMotionListener(new MouseAdapter() {
                public void mouseMoved(MouseEvent e) {
                    System.err.println("moved outside");
                }
                public void mouseDragged(MouseEvent e) {
                    System.err.println("dragged outside");
                }
            });

            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(outside);
            frame.pack();
            frame.setVisible(true);
        }
    });
}
}

感谢您的帮助。

【问题讨论】:

    标签: java mousemove stack-overflow mousemotionevent


    【解决方案1】:

    inside 中的 MouseMotionListener 正在生成一个新事件。该事件将再次被同一个MouseMotionListener 捕获,从而创建一个无限循环。由于您在前一个事件仍未完成时创建事件,因此它们将堆积起来,直到 StackOverflowError 爆炸您的应用程序。

    您的第二个代码没有这个问题,因为inside 委托给outside 并在那里完成。

    【讨论】:

    • 在第一个代码中,为什么调用的是同一个 MouseMotionListener?在 Test.this.dispatchevent(e) 中使用 Test.this;问题?我很困惑为什么它可以与 mouseMoved 一起使用。我注意到在使用 mouseMoved 时,与第二个代码相比,弹出的“移入内部”比“移出外部”要多得多。
    • 第一个代码中有两个MouseMotionListeners。鼠标在inside 面板上移动。两个监听器都会触发,因为鼠标在面板和窗口上移动。 inside 侦听器创建一个新事件并将其发布到 Swing,后者将其传递给两个侦听器。 inside 侦听器创建一个新事件并将其发布到 Swing,后者将其传递给两个侦听器。 inside 侦听器创建一个新事件并将其发布到 Swing,后者将其传递给两个侦听器。 inside 侦听器创建一个新事件并将其发布到 Swing,后者将其传递给两个侦听器...BOOM!
    猜你喜欢
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    相关资源
    最近更新 更多