java swing清除事件队列

是否有可能以标准方式做到这一点?

这是场景。

  • 在美国东部时间开始做一些昂贵的东西(美国东部时间被封锁,直到昂贵的操作结束)

  • 当EDT被阻止时,用户不断点击/拖动鼠标按钮。 所有的鼠标操作都被记录在某处。

  • 当EDT是免费的(用昂贵的东西完成),它开始处理鼠标事件。

  • 我想在第3步中放弃堆积的鼠标事件。 EDT免费后,任何新的鼠标事件都应按照常规方式处理。

    任何想法如何实现这一点。

    PS:我不可能阻止EDT被阻塞(我不控制我的程序中某些模块的行为)。

    编辑:如果我可以安全地调用“SunToolkit.flushPendingEvents()”,那么我可以在EDT开始昂贵的操作之前始终放一块玻璃板。 在昂贵的操作结束后,在EDT线上,冲洗所有事件 - 它们将进入不会做任何事情的玻璃窗格。 然后让EDT正常工作。

    编辑2:我已经添加了一个SSCCE来演示这个问题。

    
    public class BusyCursorTest2 extends javax.swing.JFrame {
    
        public BusyCursorTest2() {
    
            javax.swing.JButton wait = new javax.swing.JButton("Wait 3 seconds");
            getContentPane().setLayout(new java.awt.GridLayout(2, 1, 0, 0));
            getContentPane().add(wait);
            getContentPane().add(new javax.swing.JToggleButton("Click me"));
            setTitle("Busy Cursor");
            setSize(300, 200);
            setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
            setVisible(true);
    
            wait.addActionListener(new java.awt.event.ActionListener() {
    
                public void actionPerformed(java.awt.event.ActionEvent event) {
    
                    final java.util.Timer timer = switchToBusyCursor(BusyCursorTest2.this);
    
                    try {
                        //do something expensive in EDT
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            //do nothing
                        }
                    } finally {
                        switchToNormalCursor(BusyCursorTest2.this, timer);
                    }
                }
    
            });
        }
    
        public static java.util.Timer switchToBusyCursor(final javax.swing.JFrame frame) {
            startEventTrap(frame);
            java.util.TimerTask timerTask = new java.util.TimerTask() {
    
                public void run() {
                    startWaitCursor(frame);
                }
    
            };
            final java.util.Timer timer = new java.util.Timer();
            timer.schedule(timerTask, DELAY_MS);
            return timer;
        }
    
        public static void switchToNormalCursor(final javax.swing.JFrame frame, final java.util.Timer timer) {
            timer.cancel();
            stopWaitCursor(frame);
            stopEventTrap(frame);
        }
    
        private static void startWaitCursor(javax.swing.JFrame frame) {
            frame.getGlassPane().setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
            frame.getGlassPane().addMouseListener(mouseAdapter);
            frame.getGlassPane().setVisible(true);
        }
    
        private static void stopWaitCursor(javax.swing.JFrame frame) {
            frame.getGlassPane().setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
            frame.getGlassPane().removeMouseListener(mouseAdapter);
            frame.getGlassPane().setVisible(false);
        }
    
        private static void startEventTrap(javax.swing.JFrame frame) {
            frame.getGlassPane().addMouseListener(mouseAdapter);
            frame.getGlassPane().setVisible(true);
        }
    
        private static void stopEventTrap(javax.swing.JFrame frame) {
            frame.getGlassPane().removeMouseListener(mouseAdapter);
            frame.getGlassPane().setVisible(false);
        }
    
        private static final java.awt.event.MouseAdapter mouseAdapter = new java.awt.event.MouseAdapter() {
        };
    
        public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
    
                public void run() {
                    new BusyCursorTest2();
                }
    
            });
    
        }
    
        private static final int DELAY_MS = 250;
    
    }
    
  • 运行SSCCE

  • 点击按钮“等待3秒钟”。 它模拟一个昂贵的操作。 鼠标光标将变为繁忙状态。

  • 当光标忙时,点击切换按钮“点击我”。 如果三秒钟后,切换按钮改变其状态,则切换按钮接收到鼠标事件并且未被捕捉。

  • 我希望当光标看起来很忙时,生成的鼠标(和其他)事件会被丢弃。

    谢谢。


    好的,我终于得到了一切工作。 我发布了一个正确工作示例的SSCCE。 诀窍是使用“javax.swing.SwingUtilities.invokeLater()”方法隐藏glasspane。 将必要的代码包装在Runnable中,然后使用invokeLater调用它。 在这种情况下,Swing会处理所有的鼠标事件(因为玻璃窗会拦截它们,所以没有任何反应),然后隐藏玻璃窗。 这是SSCCE。

    public class BusyCursorTest2 extends javax.swing.JFrame {
    
        public BusyCursorTest2() {
    
            javax.swing.JButton wait = new javax.swing.JButton("Wait 3 seconds");
            getContentPane().setLayout(new java.awt.GridLayout(2, 1, 0, 0));
            getContentPane().add(wait);
            getContentPane().add(new javax.swing.JToggleButton("Click me"));
            setTitle("Busy Cursor");
            setSize(300, 200);
            setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
            setVisible(true);
    
            wait.addActionListener(new java.awt.event.ActionListener() {
    
                public void actionPerformed(java.awt.event.ActionEvent event) {
    
                    final java.util.Timer timer = switchToBusyCursor(BusyCursorTest2.this);
    
                    try {
                        //do something expensive in EDT or otherwise
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            //do nothing
                        }
                    } finally {
                        switchToNormalCursorEventThread(BusyCursorTest2.this, timer);
                    }
    
                }
    
            });
        }
    
        public static java.util.Timer switchToBusyCursor(final javax.swing.JFrame frame) {
            startEventTrap(frame);
            java.util.TimerTask timerTask = new java.util.TimerTask() {
    
                public void run() {
                    startWaitCursor(frame);
                }
    
            };
            final java.util.Timer timer = new java.util.Timer();
            timer.schedule(timerTask, DELAY_MS);
            return timer;
        }
    
        public static void switchToNormalCursorEventThread(final javax.swing.JFrame frame, final java.util.Timer timer) {
    
            Runnable r = new Runnable() {
    
                public void run() {
                    switchToNormalCursor(frame, timer);
                }
    
            };
    
            javax.swing.SwingUtilities.invokeLater(r);
    
        }
    
        public static void switchToNormalCursor(final javax.swing.JFrame frame, final java.util.Timer timer) {
            timer.cancel();
            stopWaitCursor(frame);
            stopEventTrap(frame);
        }
    
        private static void startWaitCursor(javax.swing.JFrame frame) {
            frame.getGlassPane().setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
            frame.getGlassPane().addMouseListener(mouseAdapter);
            frame.getGlassPane().setVisible(true);
        }
    
        private static void stopWaitCursor(javax.swing.JFrame frame) {
            frame.getGlassPane().setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
            frame.getGlassPane().removeMouseListener(mouseAdapter);
            frame.getGlassPane().setVisible(false);
        }
    
        private static void startEventTrap(javax.swing.JFrame frame) {
            frame.getGlassPane().addMouseListener(mouseAdapter);
            frame.getGlassPane().setVisible(true);
        }
    
        private static void stopEventTrap(javax.swing.JFrame frame) {
            java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue();
            frame.getGlassPane().removeMouseListener(mouseAdapter);
            frame.getGlassPane().setVisible(false);
        }
    
        private static final java.awt.event.MouseAdapter mouseAdapter = new java.awt.event.MouseAdapter() {
        };
    
        public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
    
                public void run() {
                    new BusyCursorTest2();
                }
    
            });
    
        }
    
        private static final int DELAY_MS = 250;
    
    }
    

    再说一遍,如果可能的话一定不要阻止。 但是如果你必须这样做,你可以像上面那样有一个忙碌的游标。

    欢迎任何评论。


    阅读这篇文章。

    基本上,长期运行的任务不应该在EDT上完成。 Java为SwingWorker提供了这样的任务。

    我会更详细地介绍,但是你不倾向于接受答案。

    链接地址: http://www.djcxy.com/p/23855.html

    上一篇: java swing clear the event queue

    下一篇: Why generate long serialVersionUID instead of a simple 1L?