当前位置: 首页 > 面试题库 >

java swing清除事件队列

吴才俊
2023-03-14
问题内容

可以以标准方式执行此操作吗?

这是场景。

  1. 开始在EDT中执行一些昂贵的操作(EDT被阻止,直到昂贵的操作结束为止)。

  2. 在阻止EDT的同时,用户继续单击/拖动鼠标按钮。所有鼠标动作都记录在某处。

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

我在步骤3中想要的是丢弃堆积的鼠标事件。EDT释放后,任何新的鼠标事件都应按常规方式处理。

关于如何实现这一目标的任何想法。

PS:对于我来说,不可能阻止EDT的阻塞(我无法控制程序中某些模块的行为)。

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

EDIT2:我添加了一个SSCCE来演示此问题。

公共类BusyCursorTest2扩展了javax.swing.JFrame {

    公共BusyCursorTest2(){

        javax.swing.JButton wait =新的javax.swing.JButton(“等待3秒”);
        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(){

            公共无效actionPerformed(java.awt.event.ActionEvent事件){

                最终的java.util.Timer timer = switchToBusyCursor(BusyCursorTest2.this);

                尝试{
                    //在EDT中做一些昂贵的事情
                    尝试{
                        Thread.sleep(3000);
                    } catch(InterruptedException e){
                        //没做什么
                    }
                }最后{
                    switchToNormalCursor(BusyCursorTest2.this,timer);
                }
            }

        });
    }

    公共静态java.util.Timer switchToBusyCursor(final javax.swing.JFrame frame){
        startEventTrap(frame);
        java.util.TimerTask timerTask = new java.util.TimerTask(){

            公共无效run(){
                startWaitCursor(frame);
            }

        };
        最终的java.util.Timer计时器=新的java.util.Timer();
        timer.schedule(timerTask,DELAY_MS);
        返回计时器;
    }

    public static void switchToNormalCursor(final javax.swing.JFrame frame,final java.util.Timer timer){
        timer.cancel();
        stopWaitCursor(frame);
        stopEventTrap(frame);
    }

    私有静态无效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);
    }

    私有静态无效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);
    }

    私有静态无效startEventTrap(javax.swing.JFrame frame){
        frame.getGlassPane()。addMouseListener(mouseAdapter);
        frame.getGlassPane()。setVisible(true);
    }

    私有静态无效stopEventTrap(javax.swing.JFrame frame){
        frame.getGlassPane()。removeMouseListener(mouseAdapter);
        frame.getGlassPane()。setVisible(false);
    }

    私有静态最终java.awt.event.MouseAdapter mouseAdapter = new java.awt.event.MouseAdapter(){
    };

    公共静态void main(String [] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){

            公共无效run(){
                新的BusyCursorTest2();
            }

        });

    }

    私有静态最终int DELAY_MS = 250;

}
  1. 运行SSCCE

  2. 单击按钮“等待3秒”。它模拟了昂贵的操作。鼠标光标将变为忙。

  3. 当光标忙时,单击切换按钮“单击我”。如果三秒钟后,切换按钮更改了其状态,则说明该切换按钮收到了鼠标事件,但未捕获鼠标事件。

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

谢谢。


问题答案:

好的,我终于可以正常工作了。我正在发布SSCCE以获取正确的示例。诀窍是使用“
javax.swing.SwingUtilities.invokeLater()”方法隐藏玻璃窗格。将必要的代码包装在Runnable中,然后使用invokeLater对其进行调用。在这种情况下,Swing处理所有鼠标事件(由于玻璃窗格拦截了鼠标事件,因此没有任何反应),然后隐藏了玻璃窗格。这是SSCCE。

公共类BusyCursorTest2扩展了javax.swing.JFrame {

    公共BusyCursorTest2(){

        javax.swing.JButton wait =新的javax.swing.JButton(“等待3秒”);
        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(){

            公共无效actionPerformed(java.awt.event.ActionEvent事件){

                最终的java.util.Timer timer = switchToBusyCursor(BusyCursorTest2.this);

                尝试{
                    //在EDT中以其他方式进行昂贵的处理
                    尝试{
                        Thread.sleep(3000);
                    } catch(InterruptedException e){
                        //没做什么
                    }
                }最后{
                    switchToNormalCursorEventThread(BusyCursorTest2.this,timer);
                }

            }

        });
    }

    公共静态java.util.Timer switchToBusyCursor(final javax.swing.JFrame frame){
        startEventTrap(frame);
        java.util.TimerTask timerTask = new java.util.TimerTask(){

            公共无效run(){
                startWaitCursor(frame);
            }

        };
        最终的java.util.Timer计时器=新的java.util.Timer();
        timer.schedule(timerTask,DELAY_MS);
        返回计时器;
    }

    public static void switchToNormalCursorEventThread(final javax.swing.JFrame frame,final java.util.Timer timer){

        Runnable r = new Runnable(){

            公共无效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);
    }

    私有静态无效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);
    }

    私有静态无效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);
    }

    私有静态无效startEventTrap(javax.swing.JFrame frame){
        frame.getGlassPane()。addMouseListener(mouseAdapter);
        frame.getGlassPane()。setVisible(true);
    }

    私有静态无效stopEventTrap(javax.swing.JFrame frame){
        java.awt.Toolkit.getDefaultToolkit()。getSystemEventQueue();
        frame.getGlassPane()。removeMouseListener(mouseAdapter);
        frame.getGlassPane()。setVisible(false);
    }

    私有静态最终java.awt.event.MouseAdapter mouseAdapter = new java.awt.event.MouseAdapter(){
    };

    公共静态void main(String [] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){

            公共无效run(){
                新的BusyCursorTest2();
            }

        });

    }

    私有静态最终int DELAY_MS = 250;

}

同样,绝不能阻止EDT。但是,如果必须的话,您可以像上面那样使用忙碌的游标。

欢迎任何意见。



 类似资料:
  • 问题内容: 我正在使用RQ,我有一个队列包含数千个项目,而另一个队列我创建了一段时间用于测试,现在已经空了并且没有使用。我想知道如何从队列中删除所有作业,然后完全删除队列? 道歉的基本问题,但我无法在RQ文档中找到有关此信息,对于Redis和RQ来说,我都是新手…预先感谢! 问题答案: RQ提供了使任何队列为空的方法: 如果仍然存在,也可以对队列执行相同的操作。 清理使用 安装rq-dashboa

  • 在chrome上,当用户单击清除按钮时,搜索输入会触发“搜索”事件。 是否有一种方法可以在Internet Explorer10上用javascript捕获相同的事件?

  • 22.9.Clean clean 任务是一个 Delete 的实例. 它只是删除 dir 属性指定的目录. 表22.11.java 插件 - Clean 的属性 任务属性 类型 默认值 dir File buildDir

  • 问题内容: 在ubuntu 10.11上进行简单的apt- get更新后,我失去了svn轮询的可能性。我的所有项目都无法再轮询svn。插件更新中心显示此插件有可用的更新(1.34-> 1.37),但无法使用Web界面或cli进行更新。Jenkins日志显示了与Subversion插件相关的大量错误 等…等… 我用手移除了: 但该插件仍会列在更新区域中。 问题:删除此插件的所有引用并重新安装的正确方

  • 我刚才看到了三个方法的文档,当我们在工作线程中工作时,它们可以用来在UI线程中执行一段代码。方法有: > public final void runOnUIThread(Runnable action)-在UI线程上运行指定的操作。如果当前线程是UI线程,则立即执行该操作。如果当前线程不是UI线程,则将操作发布到UI线程的事件队列中 public boolean post(Runnable act