JavaFX – 许多静态FXML控制器

存在JavaFX应用程序,应用程序从Main.class文件开始,该文件extends Application

  public class Main extends Application { /** * Keep a reference to the main Stage */ public static Stage stage; /** * MainScene Controller */ public static MainScene mainSceneController; /** * The Capture Window of the application */ public static CaptureWindow captureWindowController; /** * Settings Scene Controller */ public static SettingsController settingsController; @Override public void start(Stage primary) throws Exception { stage = primary; .......... // CaptureWindow FXMLLoader loader1 = new FXMLLoader(getClass().getResource("/fxml/CaptureWindow.fxml")); loader1.load(); captureWindowController = loader1.getController(); // MainScene mainSceneController = new MainScene(); ......... } } 

描述

正如你在上面看到的,我有3个FXMLControllers (一个是可重用的[ extends StackPane ],其他没有)。我已经声明所有这些都是静态的,因为我想从一个FXMLController从其他FXMLControllers访问变量。我每次都使用这个策略使用JavaFX ,我觉得不好……

我如何更改下面的代码,以便从其他FXMLController访问一个FXMLController变量或方法? 没有使用static关键字可以吗?

考虑控制器由不同的类表示,这些类可以位于不同的包中。


在写这个问题之前,我还看了一下FXML Controller中的Static @FXML变量

实际上这个问题的答案看起来有点复杂,它与MVC模式和它的演化有关,直到现在。我们将使用MVP模式。

经过长时间的讨论,我在这个网站http://martinfowler.com/eaaDev/uiArchs.html上找到了一个链接,定义了从Smalltalk的旧时代到现在使用的不同模式的历史演变。


实际的解决方案是使用Model Viewer Presenter Pattern(MVP) ,可以使用这些图像直观地描述:

在此处输入图像描述

在此处输入图像描述

欲了解更多信息,请阅读( http://www.wildcrest.com/Potel/Portfolio/mvp.pdf


有关JavaFX的示例,请查看James_D答案( 使用JavaFx应用MVC )


最后但并非最不重要的是看看这里的评论:

最后:

如果有任何不准确的地方,请随时编辑。

我认为您不应该使用static关键字声明@FXML带注释的属性。 请参阅此GitHub项目 ,了解如何执行此操作。 就像你只在需要时实例化控制器一样,你的应用程序将是无状态的。

JavaFx主要由一组[精心设计]工具组成,但不幸的是,它本身并没有为创建复杂的UI设计提供良好的框架,例如MVC / MVP模式,视图流和多个控制器上的操作,所以你必须依赖第三方例如,应用程序框架:

  • DataFx
  • JacpFx
  • JRebirth
  • JFX Flow

在我看来,没有一个被广泛使用或成熟到足以被认为是事实上的标准,但鼓励使用它们。


使用DataFx的示例

DataFx使用名为Flow的概念来关联共享事件流(以及可能的数据)的视图。 通过将Flow与EventSystem结合使用,您可以定义和访问其他控制器上的方法,并将自定义事件侦听器分配给与共享流的不同控制器中的JavaFx节点关联的各种事件。

以下是DataFx示例中的一个示例,它表示具有不同FXML文件和控制器的两个独立的发送者和接收者视图:

在此处输入图像描述

 public class EventSystemDemo extends Application { @Override public void start(Stage primaryStage) throws Exception { HBox box = new HBox(); box.setSpacing(12); box.setPadding(new Insets(12)); box.setFillHeight(true); box.setAlignment(Pos.CENTER); Flow senderFlow = new Flow(ProducerController.class); box.getChildren().add(senderFlow.start()); Flow receiverFlow = new Flow(ReceiverController.class); box.getChildren().add(receiverFlow.start()); primaryStage.setScene(new Scene(box)); primaryStage.show(); } public static void main(String... args) { launch(args); } } 

发件人视图控制器:

 @ViewController("producer.fxml") public class ProducerController { @FXML @EventTrigger() private Button sendButton; @FXML private TextField textField; @EventProducer("test-message") private String getMessage() { return textField.getText(); } } 

接收器视图控制器:

 @ViewController("receiver.fxml") public class ReceiverController { @FXML private Label messageLabel; @OnEvent("test-message") private void onNewChatMessage(Event e) { messageLabel.setText(e.getContent()); } } 

发件人查看:

                 

接收者视图:

                

进一步阅读:

http://www.oracle.com/technetwork/java/javafx/community/3rd-party-1844355.html

http://www.guigarage.com/2015/02/quick-overview-datafx-mvc-flow-api/

http://www.guigarage.com/2014/05/datafx-8-0-tutorials/

http://jacpfx.org/2014/11/03/JacpFX_DataFX_a_perfect_match.html

传递参数JavaFX FXML

您可以实现自己的控制器工厂,这样您就可以创建自己的控制器上下文。

我使用带有javaFX的spring,并且我已经使用spring实现了我自己的控制器工厂,这样你可以在另一个中注入一个控制器(你不应该需要它,因为那些连接应该在模型上)

如果你想用Java fx尝试spring: 如何使用springdependency injection连接多个fxml控制器?

当然,您应该使用可帮助您构建代码的应用程序框架。

如果您想尝试JRebirth,只需将您的应用程序分为4个部分:

  • MainModel由:
    • MainSceneModel
    • CaptureWindowModel
    • SettingsModel

您可以使用getModel(Model.class)访问任何人,也可以使用sendWave(Wave)发送异步消息。

MainModel可以使用innerComponent将子模型紧密链接到它。

它使用起来非常简单,如果你对我感兴趣,我可以给你一个示例应用程序原型,让我知道。