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

这是场景。

  • 开始在EDT中执行一些昂贵的操作(EDT被阻止,直到完成昂贵的操作为止)。
  • 在阻止EDT的同时,用户继续单击/拖动鼠标按钮。所有鼠标 Action 都记录在某处。
  • 当EDT免费(用昂贵的东西完成)时,它开始处理鼠标事件。

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

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

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

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

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

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

    公共(public)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(“忙光标”);
    setSize(300,200);
    setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
    setVisible(true);

    wait.addActionListener(new java.awt.event.ActionListener(){

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

    最后的java.util.Timer计时器= switchToBusyCursor(BusyCursorTest2.this);

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

    });
    }

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

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

    私有(private)静态无效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)静态无效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)静态无效startEventTrap(javax.swing.JFrame frame){
    frame.getGlassPane()。addMouseListener(mouseAdapter);
    frame.getGlassPane()。setVisible(true);
    }

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

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

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

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

    });

    }

    私有(private)静态最终int DELAY_MS = 250;

    }
  • 运行SSCCE
  • 单击“等待3秒”按钮。它模拟了昂贵的操作。鼠标光标将变为忙。
  • 当光标忙时,单击切换按钮“单击我”。如果三秒钟后,切换按钮更改了其状态,则鼠标事件被切换按钮接收到,并且没有被捕获。

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

    谢谢。

    最佳答案

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

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

    公共(public)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(“忙光标”);
    setSize(300,200);
    setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
    setVisible(true);

    wait.addActionListener(new java.awt.event.ActionListener(){

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

    最后的java.util.Timer计时器= switchToBusyCursor(BusyCursorTest2.this);

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

    }

    });
    }

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

    公共(public)无效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(){

    公共(public)无效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)静态无效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)静态无效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)静态无效startEventTrap(javax.swing.JFrame frame){
    frame.getGlassPane()。addMouseListener(mouseAdapter);
    frame.getGlassPane()。setVisible(true);
    }

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

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

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

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

    });

    }

    私有(private)静态最终int DELAY_MS = 250;

    }

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

    欢迎任何意见。

    09-30 15:52
    查看更多