Question

I've been trying to implement mouse motion event dispatches but I continue to get a stack overflow error. It works for the mouseMoved(MouseEvent e) method but not for mouseDragged(MouseEvent e). Does anybody have a clue as to why? Are there any solutions?

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

My actual project uses many inside components and my goal is to have each component implement their own mouse press/click/release actions and have the frame handle mouse motions and dragging that influences all of the components.

Here is a similar code that does work for both mouse motion methods.

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

Help is appreciated.

Was it helpful?

Solution

Your MouseMotionListener in the inside is generating a new event. That event will be caught again by the very same MouseMotionListener, creating an endless loop. Since you are creating an event when the previous one is still unfinished, they will stack up until a StackOverflowError explodes your application.

Your second code does not have this problem because the inside delegates to the outside and it finishes there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top