[英]JavaFX - Many Static FXML Controllers
存在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使用名为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<String> e) {
messageLabel.setText(e.getContent());
}
}
发件人查看:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="12.0" style="-fx-border-color: darkgrey; -fx-border-width: 2;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label text="Sender">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
<TextField fx:id="textField" />
<Button fx:id="sendButton" mnemonicParsing="false" text="send" />
</children>
<padding>
<Insets bottom="12.0" left="12.0" right="12.0" top="12.0" />
</padding>
</VBox>
接收者视图:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="12.0" style="-fx-border-color: darkgrey; -fx-border-width: 2;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label text="Receiver">
<font>
<Font name="System Bold" size="24.0" />
</font></Label>
<Label fx:id="messageLabel" />
</children>
<padding>
<Insets bottom="12.0" left="12.0" right="12.0" top="12.0" />
</padding>
</VBox>
进一步阅读:
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
您可以实现自己的控制器工厂,这样您就可以创建自己的控制器上下文。
我使用spring和javaFX,并且我已经使用spring实现了我自己的控制器工厂,这样你可以在另一个中注入一个控制器(你不应该需要它,因为那些连接应该在模型上)
如果你想用Java fx尝试spring: 如何使用spring依赖注入连接多个fxml控制器?
当然,您应该使用可帮助您构建代码的应用程序框架。
如果您想尝试JRebirth,只需将您的应用程序分为4个部分:
您可以使用getModel(Model.class)访问任何人,也可以使用sendWave(Wave)发送异步消息。
MainModel可以使用innerComponent将子模型紧密链接到它。
它使用起来非常简单,如果你对我感兴趣,我可以为你做一个示例应用程序原型让我知道。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.