【问题标题】:Handle concurrent events Java Swing event handler处理并发事件 Java Swing 事件处理程序
【发布时间】:2017-02-13 07:41:23
【问题描述】:

我有以下Java 代码,它将JRadioButton 添加到JPanel 并处理其鼠标单击事件

    JRadioButton offline  = new JRadioButton();
    offline.setText("Offline Mode");

    modePanel.add(offline);

    modePanel.setLayout(new GridLayout(2,1));
    offline.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    offlineClicked(evt);
                }
            });

函数offlineClicked 大约需要 1 分钟 才能完全执行。 并且在其执行完成之前,不会处理执行的其他操作。

当offlineClicked 完成执行时,此后执行的所有操作似乎都进入事件队列并处理 FIFO。

因此,用户界面似乎已进入挂起状态。

可以做些什么来同时处理摆动句柄事件而不是等到最后一个完全执行。

【问题讨论】:

  • 标准技术是永远不要在事件线程上执行应用程序工作。始终在单独的处理线程上运行应用程序工作,以便 UI 可以保持响应。有关于这个主题的完整书籍和教程,做一些谷歌搜索。从 Oracle 的教程开始。
  • 您正在寻找按钮的SwingWorker 和ActionListener; for example (of SwingWorker)
  • 每次点击都必须得到处理吗?或者您是否希望在第一次点击的初始过程完成之前忽略点击? - 在实现并发解决方案时(即使使用 SwingWorker 等),您必须考虑到这一点
  • @MadProgrammer, SwingWorker 成功了,谢谢。

标签: java swing concurrency event-handling jpanel


【解决方案1】:

当 mouselistener 事件被触发时,它在事件调度线程(重绘屏幕的 swing gui thead)上运行。如果您将逻辑代码放在 gui 线程中,那么您的 gui 将冻结,直到逻辑完成并将 gui 线程返回到 swing。您可以使用 swingworker 或其他选项是简单地启动一个新线程并让 gui 线程返回,以便它可以让其他 gui 事件处理。在新线程中执行耗时的逻辑,它在事件循环之外运行,因此 Swing 在异步运行时不会冻结。您必须在调度线程上运行所有摇摆代码,因此当逻辑完成时,因为您不再在调度线程上,您必须将其添加到事件队列中。

java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
        // you can now safely use swing components
        new frame.setVisible(true);
    }
} );

【讨论】:

    猜你喜欢
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 2018-01-25
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多