【问题标题】:How to broadcast an Event in JavaFX如何在 JavaFX 中广播事件
【发布时间】:2015-10-20 06:42:26
【问题描述】:

给定一个 JavaFX 应用程序,该应用程序具有按层次结构组织的多个演示者和视图。如何将事件从父演示者广播到子演示者/视图?

我的架构如下所示:我有一个 MainPresenter,它位于层次结构的顶部

public class MainPresenter {

    @FXML private TreeView<String> navigation;
    @FXML private AnchorPane       contentView;
    @Autowired private MainView    mainView;
    @Autowired private DetailView  detailView;

    @FXML
    public void initialize() {

        // register a handler for selection of treeview items
        navigation.getSelectionModel().selectedItemProperty().addListener(
            new ChangeListener<TreeItem<String>>() {
                // ...          
                contentView.getChildren().clear();
                contentView.getChildren().add(detailView);
                contentView.fireEvent(new ResourceEvent(ResourceEvent.SELECTED, model));
                // ...
            }
        );
    }
}

对于选中项的详细视图还有一个presenter:

public class DetailPresenter {

    @Autowired private DetailView       view;

    @PostConstruct
    public void postInit() {
        // is being executed
        view.getView().addEventHandler(ResourceEvent.SELECTED, (event) -> {
            // not being invoked
        });
    }
}

我想要实现的是,每当在 TreeView 中选择一个项目时,应将此项目的 DetailView 添加到场景图中(工作),并应通知 DetailPresenter 从后端服务加载资源。 对此的一种解决方案是简单地在MainPresenter 中自动连接DetailPresenter,这不是我想要的。我想要松耦合。正如我从文档on Event Handling 中假设的那样,一个事件被分派到场景图中的所有节点,然后冒泡回到场景的根部。由于我的DetailPresenter 中的EventHandler 没有被调用,我认为该事件没有被传递。

我的问题是,如何实现这一目标?

【问题讨论】:

  • 我确定你已经解决了这个问题吗?还是?
  • 事实上我最终使用了外部发布/订阅机制。如果您将 spring 用于您的应用程序,请查看 springs 应用程序事件。我最终推出了自己的 EventBus,因为我不需要任何花哨的功能。

标签: java javafx javafx-8


【解决方案1】:

MyModel.java:

public class MyModel {
  private StringProperty myString = new SimpleStringProperty();
  public void setMyString(String myString) { this.myString.set(myString); }
  public String getMyString() { return myString.get(); }
  public StringProperty getMyStringProperty() { return myString; }
}

然后创建一个 MyModel 的实例作为单例 bean(看起来你正在使用 Spring)。并在需要的地方注入你的模型:

@Bean
public MyModel myModel() {
  return new MyModel();
}

然后注入并绑定到属性:

public class MyPresenter {
  @FXML TextField myTextField;
  @Autowired MyModel myModel;

  public void initialize() {
    myTextField.textProperty().bind(myModel.getMyStringProperty());
  }
}

如果现在有人更新了 myString 属性,那么 UI myTextField 也会更新。

您还可以在这些属性上注册一些自定义处理程序或使用 twoWayBinding。

因此您不必将其用作 UI 元素,还可以将其用作某种数据管道。

【讨论】:

    猜你喜欢
    • 2013-05-21
    • 2020-04-28
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 2016-01-25
    • 2016-06-12
    • 2017-05-04
    相关资源
    最近更新 更多