I have a JFrame (undecorated) with a Glasspane. This Frame opens a JDialog (also undecorated and has also a glassPane) and hides itself (setVisible(false)). The Glasspanes are s
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.