Reputation: 195
I have a problem where my listener does not get all of AWT Events. Or at least I hope so. My another problem is that I couldn't reconstruct the issue on a Snippet of code. :(
What I do is:
Listen to all AWTEvents (only mouse event actually),
mouse press starts a timer,
when the timer is done and the LMB is still pressed, component at mouse pointer is removed from the hierarchy.
At this point as long as I am still ppressing the LMB i get only MOUSE_EXITED and MOUSE_ENTERED events. No move, drag or even mouse released events.
As soon as I release the mouse button everything returns to normal.
Any suggestions what could cause the problem?
@Edit: code example updated
package awtbug;
import java.awt.AWTEvent;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class MyAWTBug extends JFrame{
public static void main(String[] args) {
new MyAWTBug();
}
public MyAWTBug() {
setSize(300, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(new AWTListenerPanel());
}
private class AWTListenerPanel extends JPanel implements AWTEventListener {
JPanel somePanel = new JPanel();
public AWTListenerPanel() {
Toolkit.getDefaultToolkit().addAWTEventListener(this, Long.MAX_VALUE);
this.add(somePanel);
}
@Override
public void eventDispatched(AWTEvent event) {
System.out.println("-----------------------");
System.out.println(event);
if (event instanceof MouseEvent) {
if (event.getID() == MouseEvent.MOUSE_PRESSED) {
Timer timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
modifyTree();
}
});
timer.setRepeats(false);
timer.restart();
}
}
}
private void modifyTree() {
getContentPane().remove(somePanel);
getContentPane().add(somePanel);
System.err.println("stuff done");
}
}
}
@Edit 2: I could narrow it down to the
outsideComp.remove(insideComp);
as soon as I do this, events stop coming...
Upvotes: 1
Views: 1010
Reputation: 109815
not an answer, code for test should be
(main issue) JPanel is added to already visible JFrame, LayoutManagers haven't any notifiers about (see point 2nd.)
use validate() and repaint(); as last code line, notifier, signal for LayoutManager
always recreate local variable for testing purposes
never to extends whatever for testing purpose, I'm lost in this.whateverMethod and without this
(minor but orders of events is changed) use Initial Thread
I'm ignored that JFrames Bounds never changed (too lazy)
Swing Timer should be defined as an local variable too
EDIT
only on top JComponent in components tree can to firing (and to consume all) Key and Mouse event, JPanel in this case, JPanel should be/must be set to setFocusable() for KeyEvents, and JPanel added in modifyTree() missing JFrame.(re)validate() and repaint(), then this JPanel isn't registred in components hierarchy properly, you can to test by add Hierarchy or ComponentListener to the ContentPane
.
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
public class MyAWTBug implements AWTEventListener {
private JPanel panel = new JPanel();
private JFrame frame = new JFrame();
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MyAWTBug();
}
});
}
public MyAWTBug() {
Toolkit.getDefaultToolkit().addAWTEventListener(this, Long.MAX_VALUE);
panel = new JPanel();
panel.setBackground(Color.red);
panel.setBorder(new LineBorder(Color.black, 1));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setPreferredSize(new Dimension(300, 300));
frame.pack();
frame.setVisible(true);
}
@Override
public void eventDispatched(AWTEvent event) {
System.out.println("-----------------------");
for (AWTEventListener listener : Toolkit.getDefaultToolkit().getAWTEventListeners()) {
System.out.println(listener);
}
System.out.println("-----------------------");
System.out.println(event);
if (event instanceof MouseEvent) {
if (event.getID() == MouseEvent.MOUSE_PRESSED) {
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
modifyTree();
}
});
timer.setRepeats(false);
timer.restart();
}
}
}
private void modifyTree() {
frame.remove(panel);
panel = new JPanel();
panel.setBorder(new LineBorder(Color.black, 1));
frame.add(panel);
frame.validate();
frame.repaint();
frame.setPreferredSize(new Dimension((int) Math.random() * 50 + 300, (int) Math.random() * 50 + 300));
frame.pack();
System.err.println("stuff done");
}
}
Upvotes: 2