我有一个问题,我的听众没有得到所有的AWT事件。 或者至少我希望如此。 我的另一个问题是我无法在一段代码上重建问题。 :(
我的工作是:
收听所有AWTEvents(实际只有鼠标事件),
鼠标按下启动计时器,
当计时器完成且仍按下LMB时,鼠标指针的组件将从层次结构中删除。
此时只要我仍在按下LMB,我只会获得MOUSE_EXITED和MOUSE_ENTERED事件。没有移动,拖动甚至鼠标释放事件。
一旦我松开鼠标按钮,一切都恢复正常。
任何可能导致问题的建议?
@Edit:代码示例已更新
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: 我可以把它缩小到
outsideComp.remove(insideComp);
一旦我这样做,事件就会停止......
答案 0 :(得分:2)
不是答案,测试代码应该是
(主要问题)JPanel已添加到已经可见的JFrame中,LayoutManagers没有任何通知程序(请参阅第2点。)
使用validate()和repaint();作为最后一个代码行,通知程序,LayoutManager的信号
始终为测试目的重新创建局部变量
永远不会为了测试目的扩展任何东西,我迷失在此。无论什么方法,没有这个
(次要但事件顺序已更改)使用初始线程
我忽略了JFrames Bounds从未改变过(懒得)
Swing Timer也应定义为局部变量
修改
只有在组件树中的顶级JComponent才能触发(并消耗所有)Key和Mouse事件,在这种情况下,JPanel应该/必须设置为KeyEvents的setFocusable(),并且JPanel添加了modifyTree()缺少JFrame。(重新)validate()和repaint(),然后这个JPanel没有正确地注册到组件层次结构中,你可以通过将Content Hane或ComponentListener添加到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");
}
}