[英]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.