尝试分派MouseEvents时出现Stackoverflow错误。 mouseMoved有效但mouseDragged没有

时间:2013-06-28 02:28:03

标签: java mousemove stack-overflow mousemotionevent

我一直在尝试实现鼠标移动事件调度,但我仍然遇到堆栈溢出错误。它适用于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);
        }
    });
}
}

非常感谢帮助。

1 个答案:

答案 0 :(得分:1)

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

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