gpt4 book ai didi

java - AWTEventListener 缺少事件

转载 作者:行者123 更新时间:2023-11-30 03:55:22 25 4
gpt4 key购买 nike

我遇到一个问题,即我的监听器无法获取所有 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");
}
}
}

@编辑2:我可以将范围缩小到

outsideComp.remove(insideComp);

一旦我这样做,事件就停止了......

最佳答案

不是答案,测试代码应该是

  1. (主要问题)JPanel 被添加到已经可见的 JFrame 中,LayoutManager 没有任何通知程序(请参阅第 2 点。)

  2. 使用 validate() 和 repaint();作为布局管理器的最后一个代码行、通知程序、信号

  3. 始终重新创建局部变量以进行测试

  4. 永远不要为了测试目的而扩展任何东西,我迷失在 this.whateverMethod 中,没有这个

  5. (次要但事件顺序发生了变化)使用初始线程

  6. 我忽略了 JFrames Bounds 从未改变(太懒了)

  7. Swing Timer 也应该定义为局部变量

    编辑

  8. 只有在组件树中的顶部 JComponent 才能触发(并消耗所有)按键和鼠标事件,在这种情况下是 JPanel,JPanel 应该/必须设置为 KeyEvents 的 setFocusable(),并且 JPanel 添加在modifyTree() 缺少 JFrame.(re)validate() 和 repaint(),则此 JPanel 未正确注册到组件层次结构中,您可以通过将 Hierarchy 或 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");
}
}

关于java - AWTEventListener 缺少事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23363421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com