番石榴eventbus和AWT事件线程处理结合最好的方法 [英] best way to combine guava eventbus and AWT Event thread handling

查看:184
本文介绍了番石榴eventbus和AWT事件线程处理结合最好的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当你有一个异步事件总线,并且触发事件,其中获得在UI擦肩而过,模型中可以说你有可能存在如下问题:

已注册的处理程序获取在辅助线程执行,但所有UI挥杆的改变需要在AWT事件线程中执行。
这意味着你需要在信封所有的处理程序clode EventQueue.invokeLater(...)

这貌似很多锅炉板code的。
我不知道是否有该问题的一个更聪明的解决方案。

有关扩展到一个特殊的线程内,标志着执行的处理番石榴事件总线是什么?这可能是标有annotion例如 @ExecuteWithinEDT

 类EventBusChangeRecorder {
  @Subscribe @ExecuteWithinEDT无效recordCustomerChange(的ChangeEvent发送){
    recordChange(e.getChange());
  }
}


解决方案

与异步事件总线注册的处理程序在任何线程提供的执行人选择运行它​​们执行对,不一定是工作线程。

我所做的创建执行人,该事件队列的线程上运行的东西的实现。这是pretty简单:

 公共类EventQueueExecutor实现执行人{
  @覆盖公共无效的execute(Runnable的命令){
    EventQueue.invokeLater(命令);
  }
}

您可以然后只需创建 EventBus

  EventBus eventBus =新AsyncEventBus(新EventQueueExecutor());

然后,所有的处理程序将在事件队列线程上执行。

编辑:

将事件转发的一个例子:

 公共类EventForwarder {
  私人最终EventBus uiEventBus;  公共EventForwarder(EventBus uiEventBus){
    this.uiEventBus = uiEventBus;
  }  //转发所有事件
  @订阅
  公共无效forwardEvent(对象事件){
    uiEventBus.post(事件);
  }  //或者如果你只希望事件的特定类型的转发
  @订阅
  公共无效forwardEvent(的UIEvent事件){
    uiEventBus.post(事件);
  }
}

刚刚订阅了你的主事件总线和发布所有事件到主事件总线,但是订阅所有UI组件的UI事件总线。

When you have a asynchronous event bus, and fire events, lets say within the model which get catched in the UI you have probably the following problem:

The registered handler gets executed in a worker thread, but all UI swing changes need to be executed within the AWT event thread. This means you need to envelope all your handler clode in EventQueue.invokeLater(...).

This looks like a lot of boiler plate code. I wonder if there is a smarter solution for that problem.

What about an extension to the guava event bus that marks a handler for execution within a special thread? This could be marked with a annotion e.g. @ExecuteWithinEDT:

class EventBusChangeRecorder {
  @Subscribe @ExecuteWithinEDT void recordCustomerChange(ChangeEvent e) {
    recordChange(e.getChange());
  }
}

解决方案

The handlers registered with an async event bus are executed on whatever thread the provided Executor chooses to run them on, not necessarily a worker thread.

What I've done is created an implementation of Executor that runs stuff on the event queue thread. It's pretty simple:

public class EventQueueExecutor implements Executor {
  @Override public void execute(Runnable command) {
    EventQueue.invokeLater(command);
  }
}

You can then just create your EventBus with that:

EventBus eventBus = new AsyncEventBus(new EventQueueExecutor());

Then all handlers will be executed on the event queue thread.

Edit:

An example of forwarding events:

public class EventForwarder {
  private final EventBus uiEventBus;

  public EventForwarder(EventBus uiEventBus) {
    this.uiEventBus = uiEventBus;
  }

  // forward all events
  @Subscribe
  public void forwardEvent(Object event) {
    uiEventBus.post(event);
  }

  // or if you only want a specific type of event forwarded
  @Subscribe
  public void forwardEvent(UiEvent event) {
    uiEventBus.post(event);
  }
}

Just subscribe that to your main event bus and post all events to the main event bus, but subscribe all UI components to the UI event bus.

这篇关于番石榴eventbus和AWT事件线程处理结合最好的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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