我这也有一个方案,可以评估一下
我是按照 Screen
里的 eventHub
的事件订阅机制改造的。
思路很简单,让 Screen
里的 eventHub
在业务bean里可访问既可以发送事件了。
实现:
监听ScreenOpenedEvent
事件,每次打开窗口通过反射获取eventHub
@EventListener
public void screenOpenedEventListener(ScreenOpenedEvent event) {
Screen source = event.getSource();
//获取class对象
Class<?> clazz = source.getClass();
//获取当前对象中声明的方法
Method method = null;
try {
method = clazz.getDeclaredMethod("getEventHub");
} catch (NoSuchMethodException e) {
// throw new RuntimeException(e);
}
if (method != null) {
method.setAccessible(true);
try {
eventHub = (EventHub) method.invoke(source);
} catch (IllegalAccessException | InvocationTargetException e) {
// throw new RuntimeException(e);
}
}
}
然后再定一个发送方法
public static <E> void fireEvent(E event) {
if (eventHub != null) {
eventHub.publish(((Class<E>) event.getClass()), event);
}
}
在UI控制器里
1注册订阅方法
@Override
public EventHub getEventHub() {
// 反射获取EventHub用
return super.getEventHub();
}
// 注册订阅(要 add 或 set 开头)
public Subscription addEventListener1(Consumer<DeviceOnlineEvent> listener) {
return getEventHub().subscribe(DeviceOnlineEvent.class, listener);
}
2添加订阅方法
@Subscribe
public void deviceOnlineHandler(DeviceOnlineEvent event) {
String deviceId = event.getDeviceId();
boolean online = event.isOnline();
Device device = devices.get(deviceId);
if (device != null) {
systemAuthenticator.runWithSystem(() -> device.setStatus(online ? Status.ONLINE : Status.OFFLINE));
}
}