java swing清除事件队列 [英] java swing clear the event queue

查看:127
本文介绍了java swing清除事件队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to do this in a standard manner?

以下是该方案。


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

  1. Start doing something expensive in EDT (EDT is blocked till the expensive operation is over).

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

While EDT was blocked, the user kept on clicking/dragging the mouse buttons. All the mouse actions are recorded somewhere.

当EDT空闲时(使用昂贵的东西完成),它开始处理鼠标事件。

When EDT is free (done with the expensive stuff), it starts to process the mouse events.

我在步骤3中想要的是丢弃堆积的鼠标事件。在EDT免费之后,任何新的鼠标事件都应该以通常的方式处理。

What I want in step 3 is to discard the mouse events that have piled up. After the EDT is free, any new mouse event should be handled in the usual manner.

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

Any ideas on how to achieve this.

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

PS: It is not possible for me to prevent the EDT from getting blocked (I do not control the behavior of some of the modules in my program).

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

If I can safely call "SunToolkit.flushPendingEvents()" then I can always put a glasspane before starting the expensive operation in EDT. After the expensive operation is over then on the EDT thread, flush all the events - they will go to a glass pane that wont do anything. And then let EDT work as normal.

EDIT2:
我已经添加了一个SSCCE来证明这个问题。

I have added a SSCCE to demonstrate the issue.



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;

}




  1. 运行SSCCE

  1. Run the SSCCE

点击等待3秒钟按钮。它模拟了昂贵的操作。鼠标光标将变为忙碌。

Click on the button "Wait 3 seconds". It simulates an expensive operation. The mouse cursor will change to busy.

光标处于忙碌状态时,单击切换按钮单击我。如果在三秒钟之后,切换按钮改变其状态,则切换按钮接收到鼠标事件并且没有被捕获。

While the cursor is busy, click on the toggle button "Click me". If after three seconds, the toggle button changes its state, then the mouse event was received by the toggle button and was not trapped.

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

I want that while the cursor looks busy, the generated mouse (and other) events be discarded.

谢谢。

推荐答案

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

OK, I finally got everything to work. I am posting the SSCCE for a correctly working example. The trick is to hide the glasspane using "javax.swing.SwingUtilities.invokeLater()" method. Wrap the necessary code in a Runnable and then invoke it using invokeLater. In such a case, Swing processes all the mouse events (nothing happens since a glasspane intercepts them), and then hides the glasspane. Here is the 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(如果可能的话)不得被阻止。但是如果必须的话,你可以使用上面一个工作忙碌的光标。

Again, EDT if at all possible must not be blocked. But if you have to, you can have a working busy cursor as above.

欢迎任何评论。

这篇关于java swing清除事件队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆