Ошибка переполнения стека при попытке отправки MouseEvents. mouseMoved работает, но mouseDragged - нет

Я пытался реализовать диспетчеризацию событий движения мыши, но продолжаю получать ошибку переполнения стека. Он работает для метода 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 ответ

Решение

Ваш MouseMotionListener в inside генерирует новое событие. Это событие снова будет поймано тем же MouseMotionListener, создавая бесконечный цикл. Поскольку вы создаете событие, когда предыдущий еще не завершен, они будут складываться до StackruError взрывает ваше приложение.

Ваш второй код не имеет этой проблемы, потому что inside делегаты outside и это заканчивается там.

Другие вопросы по тегам