【问题标题】:Can I add a MouseMotionListener to another thread in Java?我可以将 MouseMotionListener 添加到 Java 中的另一个线程吗?
【发布时间】:2013-03-08 22:20:52
【问题描述】:

我有一个非常繁忙的线程试图做所有事情,它开始减慢我的 MouseMotionListener。我想我会把监听器放在另一个线程中,以确保它总是尽可能快地运行,但是一旦我做到了:

import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

public class MouseListenerThread extends Thread implements MouseMotionListener {

    public void run(){
        //Concurrency happens here  
    }

    public void mouseDragged(MouseEvent e) {
        // Do something 
    }

    public void mouseMoved(MouseEvent e) {
        // Do something else
    }
}

我意识到虽然我可以将这个其他对象函数用作鼠标侦听器,但我不能同时执行此操作。有什么办法可以使用run函数来实现监听吗?我也接受任何其他加快听众速度的解决方案。

谢谢!

【问题讨论】:

  • 在 Swing 中,您不应该在事件调度线程中做任何长时间运行的事情。您非常繁忙的线程应该是您创建的其他线程。您的鼠标侦听器将从事件调度线程中调用,因此这两个线程不应相互干扰。
  • 如果您有影响EDT 的进程,请考虑将该功能放在SwingWorker 中。 MouseListeners 只能在EDT 中找到,
  • 所以你的意思是切换两个类,让所有的业务转到备用线程,让所有的鼠标都听它在哪里?

标签: java multithreading swing mouseevent


【解决方案1】:

接收mouseDragged 等的实际侦听器必须在事件调度线程 (EDT) 上。在这些事件处理方法中完成的任何“非 GUI”工作都可以使用 SwingWorker 或任何其他线程方法转移到其他线程。

所有 GUI 工作都必须在事件调度线程中,因此如果事件处理程序因 GUI 问题而变慢,您可能会遇到麻烦,但您可以使用 SwingUtilities.InvokeLater 触发任何线程来为 EDT 安排一些工作线。您也可以使用InvokeAndWait,但这开始将您的 GUI 与支持的图形紧密结合...

【讨论】:

  • 哈哈,有点像。好吧,很多带有大 for 循环的密集内容可以很容易地放在其他地方,所以当这个东西除了绘图和鼠标监听之外几乎什么都不做时,这和我预期的一样多,对吧?
  • All GUI work must be in the main thread --> 主线程与GUI线程(EDT)不同。
  • @John3136 我仍然对你提到的InvokeLater 感到困惑。如果你的意思是SwingUtilities.InvokeLater() JavaDoc 很清楚地表明传递给它的Runnable 将在 EDT 上执行。
  • @JasonBraucht 非常好。我已将答案编辑为更准确。
【解决方案2】:

所有事件都由事件调度线程调度。将鼠标监听器放在另一个线程中绝对不会有任何区别,因为事件方法将在 EDT 的上下文中得到通知

Swing 是一个单线程框架。这意味着与 UI 的所有交互都必须在 EDT 上下文中执行。因此,即使您可以将工作卸载到另一个线程,您也需要使用 EDT 重新同步对 UI 的任何更改/更新。

您可以阅读Concurrency in Swing 了解详情。

如果您在 EDT 中执行长时间运行/阻塞的任务,您可能希望考虑使用SwingWorker,这将允许您在单独的线程中运行任务,但提供了简化更新 UI 过程的方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2015-09-11
    相关资源
    最近更新 更多