JFrame Glasspane is also over JDialog but shouldn't

假如想象 提交于 2019-12-02 13:13:28

Looking at you source code, you only ever register the frame's glass pane to the AWTListener. Now, on the surface, this doesn't seem like a bad thing. The AWTListener will be notified of ALL the mouse events in the system, but the instance of GlassPane that is actually receiving the events will only know about the frame...

Basically, this means that the dialogGlas will never receive any events, as it's not registered.

First, you need to register both the frameGlas and dialogGlas as listeners.

Second, you shouldn't be trying to "guess" the target. MouseEvent (in fact all events) have a source. You should be comparing the source with the target so you can react to events only when they occur on components you're interested in...

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

    static JFrame frame;
    static JDialog dialog;

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }


                frame = new JFrame();
                frame.setSize(600, 600);
                GlassPane frameGlas = new GlassPane(frame);
                frame.setGlassPane(frameGlas);
                frame.setVisible(true);

                frameGlas.setVisible(true);
                dialog = new JDialog(frame);

                dialog.setSize(100, 100);
                GlassPane dialogGlas = new GlassPane(dialog);
                dialog.setGlassPane(dialogGlas);
                dialogGlas.setVisible(true);
                dialog.setVisible(true);

                // Register a listener for the frameGlas
                Toolkit.getDefaultToolkit().addAWTEventListener(
                        frameGlas,
                        AWTEvent.MOUSE_MOTION_EVENT_MASK
                        | AWTEvent.MOUSE_EVENT_MASK);
                // Register a listener for the dialogGlas
                Toolkit.getDefaultToolkit().addAWTEventListener(
                        dialogGlas,
                        AWTEvent.MOUSE_MOTION_EVENT_MASK
                        | AWTEvent.MOUSE_EVENT_MASK);
            }
        });
    }

    public class GlassPane extends JPanel implements AWTEventListener {

        private static final long serialVersionUID = 5110857185182004819L;
        private final Window target;

        public GlassPane(Window target) {
            super(null);
            this.target = target;

        }

        @Override
        public void eventDispatched(AWTEvent event) {
            if (event instanceof MouseEvent) {

                MouseEvent originalEvent = (MouseEvent) event;

                MouseEvent e = originalEvent;
                Component source = e.getComponent();
                System.out.println("Source: " + source);
                System.out.println("Target: " + target);
                if (target != null && target.equals(source)) {
                    e = SwingUtilities.convertMouseEvent(
                            ((MouseEvent) event).getComponent(),
                            (MouseEvent) event, this);

                    if (e.getID() == MouseEvent.MOUSE_PRESSED) {

                        Point p = target.getLocationOnScreen();
                        System.out.println(p.getX());
                    }
                }
            }
        }
    }
}

Now, off the top of my head, the problem you're having with MouseListener is that they are greedy, they prevent the events from cascading beyond the component they are registered on.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!