Я пишу приложение JavaFX (JavaSE) с CDI (Weld). Я пытаюсь использовать события CDI для замены ужасной системы событий JavaFX (свойства JavaFX).
Я смог позволить CDI правильно создавать мои контроллеры JavaFX. Это означает, что при загрузке FXML контроллер создается CDI (с использованием FXLoader.setControllerFactory
). К сожалению, как только я добавил @Observe в один контроллер, CDI начал создавать несколько экземпляров этого контроллера. это безумие.
Похоже, я просто не понимаю правильную семантику fire()
. С каких это пор fire()
будут создавать наблюдатели ?! Может быть, это как-то связано с @Dependent
scope.
Я сделал перехватчик для отправки события, когда какое-либо свойство где-либо изменяется (в моем случае это фоновая задача, которая обновляет свойство Progress). (Не обращайте внимания на ObservableSourceLiterral
и @ObservableSource
, это просто не для того, чтобы запускать события для всех)
@ObservableProperty
@Interceptor
public class CDIPropertyWatcher {
@Inject
private Event<PropertyChangedEvent> listeners;
@AroundInvoke
public Object onPropertyCalled(InvocationContext ctx) throws Exception {
String method = ctx.getMethod()
.getName();
if (method.startsWith("set")) {
Object result = ctx.proceed();
String propertyName = method.substring(3, 4)
.toLowerCase() + method.substring(4);
listeners.select(new ObservableSourceLiterral(ctx.getTarget().getClass().getSuperclass()))
.fire(new PropertyChangedEvent(ctx.getTarget(), propertyName));
return result;
} else {
return ctx.proceed();
}
}
}
Вот установщик в моем классе Задач:
@ObservableProperty
public void setProgress(double progress) {
this.progress = progress;
}
Это метод моего контролера, ответственного за получение события:
public void onProgressTaskChanged(@Observes @ObservableSource(Task.class) PropertyChangedEvent evt)
{
Double progress = evt.getSource(Task.class).getProgress();
System.out.println("onProgressTaskChanged "+progress+" "+this);
if (progressBar!=null)
{
Platform.runLater(() -> progressBar.setProgress(progress));
}
}
Я ожидаю, что когда я запускаю событие, оно принимается фактическими существующими наблюдателями, а не создает новых.