簡體   English   中英

組合guava eventbus和AWT Event線程處理的最佳方法

[英]best way to combine guava eventbus and AWT Event thread handling

當你有一個異步事件總線和fire事件時,讓我們說在UI中捕獲的模型中你可能有以下問題:

已注冊的處理程序在工作線程中執行,但所有UI swing更改都需要在AWT事件線程中執行。 這意味着您需要在EventQueue.invokeLater(...)包含所有處理程序clode。

這看起來像很多鍋爐板代碼。 我想知道是否有更智能的解決方案來解決這個問題。

guava事件總線的擴展如何標記在特殊線程中執行的處理程序? 這可以用annotion標記,例如@ExecuteWithinEDT

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

使用異步事件總線注冊的處理程序在提供的Executor選擇運行它們的任何線程上Executor ,而不一定是工作線程。

我所做的是創建了一個Executor的實現,它在事件隊列線程上運行東西。 這很簡單:

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

然后,您可以使用以下方法創建EventBus

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

然后所有處理程序將在事件隊列線程上執行。

編輯:

轉發事件的示例:

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);
  }
}

只需訂閱您的主事件總線並將所有事件發布到主事件總線,但是將所有UI組件訂閱到UI事件總線。

您可以創建僅在AWT線程上調度的EventBus:

EventBus mybus = new AsyncEventBus("awt",
    new Executor() {
        public void execute (Runnable cmd) {
            if (EventQueue.isDispatchThread()) {
                cmd.run();
            } else {
                EventQueue.invokeLater(cmd);
            }
        }
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM