AWTEventListener缺少事件

时间:2014-04-29 11:29:29

标签: java swing awt mouse listener

我有一个问题,我的听众没有得到所有的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);

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

1 个答案:

答案 0 :(得分:2)

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

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

  2. 使用validate()和repaint();作为最后一个代码行,通知程序,LayoutManager的信号

  3. 始终为测试目的重新创建局部变量

  4. 永远不会为了测试目的扩展任何东西,我迷失在此。无论什么方法,没有这个

  5. (次要但事件顺序已更改)使用初始线程

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

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

    修改

  8. 只有在组件树中的顶级JComponent才能触发(并消耗所有)Key和Mouse事件,在这种情况下,JPanel应该/必须设置为KeyEvents的setFocusable(),并且JPanel添加了modifyTree()缺少JFrame。(重新)validate()和repaint(),然后这个JPanel没有正确地注册到组件层次结构中,你可以通过将Content Hane或ComponentListener添加到ContentPane进行测试

  9. 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");
        }
    }