如何将 FX 控制器与主应用程序连接
How to connect FX controller with main app
我有一个主应用程序 class 和一个 fxmlController class 但我纠结于 connecting/organizing(混淆了它们的调用方式以及我应该如何组织它们以使 GUI 连接业务逻辑)业务逻辑和 GUI。谁能告诉我调用以下函数的顺序,或者谁能帮助我如何调用它们?
主要class:
public void Main() //constructor
public static void main() // our main
public void start() //I don't know what it is, what purpose it has
// and where should be called
//Note: In main function there is a call as following
fxmlController class:
public void initialize() //I don't know what it is and what purpose it has
public fxmlController() // which function should be called here....
注意:我知道 FXMLLoader();
请有人解释
控制器绑定在你的fxml文件或者你第一次调用主视图的地方。
因此您可以在 xml 或启动器中的 FXMLLoader#setController()
方法中使用 fx:controller
属性。
我认为 FXML 文件及其对应的控制器是管理用户界面的一对。在较大的应用程序中,您可能有几个这样的 FXML 控制器对,它们构成了用户界面的不同部分。在每一对中,FXML 文件定义 UI 的布局,控制器定义逻辑(即它通常处理用户输入等)。
虽然您说的是 "know about FXMLLoader
",但如果您完全理解这一点,您实际上就会理解您所问的其他一些事情,所以:
FXML 文件定义的用户界面及其控制器由 FXMLLoader
加载到内存中。在最简单的设置中,控制器由 FXML 文件根元素中的 fx:controller
属性定义。当在 FXMLLoader
上调用 load()
方法时,它:
- 加载 FXML 文件
- 通过调用其无参数构造函数
,创建由 fx:controller
属性指定的控制器 class 的实例
- 将控制器中任何
@FXML
注释字段的值设置为用匹配的 fx:id
属性定义的元素
- 注册映射到控制器中方法的任何事件处理程序
- 调用控制器上的
initialize()
方法(如果有的话)。
注意这些事件的顺序:在注入@FXML
注释字段之前调用构造函数,但在initialize()
之后调用方法.这意味着您可以在 initialize()
方法中访问(和配置)和 @FXML
注释的字段,但不能在构造函数中访问。在控制器 classes 中不定义任何构造函数而只使用默认值是很常见的(至少在简单的应用程序中)。
您的应用程序中可以有与 need/want 一样多的 FXML/controller 对。每个 FXML 文件都应该有自己的控制器 class。如果您想要它定义的 UI 的多个实例,您可以根据需要多次加载 FXML 文件:每次 FXMLLoader
都会为您创建一个与 [= 关联的新控制器实例105=] 你加载的元素。
Application
子class(你叫它Main
)代表了整个应用。每个应用程序应该只有一个这样的 class,并且只有一个实例,它是由 FX 工具包为您创建的。
当您启动 FX 应用程序(我将在下面描述)时,FX 工具包也会启动。然后你的 Application
subclass 的一个实例被创建,它的 init()
方法被调用(如果你没有定义一个,默认实现什么也不做)。然后启动 FX 应用程序线程,并在该线程上调用 Application
subclass 实例的 start()
方法。
您的 start()
方法应该只做很少的工作。通常它会加载您的 "main" fxml 文件,将生成的 UI 放在场景中,将场景放在舞台上,然后显示舞台。所有逻辑都将由 FXML 文件的控制器处理,而不是 Application
subclass.
在更高级的应用程序中,您可能会启动一些后台服务 and/or 在您的 init()
方法中创建一些数据模型,并在 start()
方法中将它们与控制器连接,但是上面的想法是基础。
实际的启动过程可以通过几种方式发生。如果您使用的是标准 Oracle JRE,则启动 Application
subclass with
java Main
(where Main extends Application
) 将导致上述过程发生;换句话说,FX 工具包启动,创建 Main
的实例,调用其 init()
方法,并在 FX 应用程序线程上调用其 start()
方法。
其他环境(尤其是 IDE)不知道 JavaFX 启动过程,并期望您正在执行的 class 有一个 public static void main(String[] args)
方法,就像任何标准 Java申请class。为了支持这些环境,您的 Application
subclass 定义一个 main(...)
方法是很常见的,它只调用 launch(...)
(从 Application
继承的静态方法) . launch
方法强制 FX 工具包启动等。它在任何应用程序生命周期内只能调用一次。
所以现在你有这样的东西:
package com.example ;
// imports...
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// just load fxml file and display it in the stage:
FXMLLoader loader = new FXMLLoader(getClass().getResource("mainUI.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
// main method to support non-JavaFX-aware environments:
public static void main(String[] args) {
// starts the FX toolkit, instantiates this class,
// and calls start(...) on the FX Application thread:
launch(args);
}
}
那么你会得到 mainUI.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import java.util.ArrayList?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.MyController">
<Label fx:id="label1"/>
<Label fx:id="label2"/>
</VBox>
和控制器
package com.example ;
// imports...
public class MyController {
@FXML
private Label label1 ;
@FXML
private Label label2 ;
// called by the FXML loader after the labels declared above are injected:
public void initialize() {
// do initialization and configuration work...
// trivial example, could also be done directly in the fxml:
label1.setText("Foo");
label2.setText("Bar");
}
}
我有一个主应用程序 class 和一个 fxmlController class 但我纠结于 connecting/organizing(混淆了它们的调用方式以及我应该如何组织它们以使 GUI 连接业务逻辑)业务逻辑和 GUI。谁能告诉我调用以下函数的顺序,或者谁能帮助我如何调用它们?
主要class:
public void Main() //constructor
public static void main() // our main
public void start() //I don't know what it is, what purpose it has
// and where should be called
//Note: In main function there is a call as following
fxmlController class:
public void initialize() //I don't know what it is and what purpose it has
public fxmlController() // which function should be called here....
注意:我知道 FXMLLoader();
请有人解释
控制器绑定在你的fxml文件或者你第一次调用主视图的地方。
因此您可以在 xml 或启动器中的 FXMLLoader#setController()
方法中使用 fx:controller
属性。
我认为 FXML 文件及其对应的控制器是管理用户界面的一对。在较大的应用程序中,您可能有几个这样的 FXML 控制器对,它们构成了用户界面的不同部分。在每一对中,FXML 文件定义 UI 的布局,控制器定义逻辑(即它通常处理用户输入等)。
虽然您说的是 "know about FXMLLoader
",但如果您完全理解这一点,您实际上就会理解您所问的其他一些事情,所以:
FXML 文件定义的用户界面及其控制器由 FXMLLoader
加载到内存中。在最简单的设置中,控制器由 FXML 文件根元素中的 fx:controller
属性定义。当在 FXMLLoader
上调用 load()
方法时,它:
- 加载 FXML 文件
- 通过调用其无参数构造函数 ,创建由
- 将控制器中任何
@FXML
注释字段的值设置为用匹配的fx:id
属性定义的元素 - 注册映射到控制器中方法的任何事件处理程序
- 调用控制器上的
initialize()
方法(如果有的话)。
fx:controller
属性指定的控制器 class 的实例
注意这些事件的顺序:在注入@FXML
注释字段之前调用构造函数,但在initialize()
之后调用方法.这意味着您可以在 initialize()
方法中访问(和配置)和 @FXML
注释的字段,但不能在构造函数中访问。在控制器 classes 中不定义任何构造函数而只使用默认值是很常见的(至少在简单的应用程序中)。
您的应用程序中可以有与 need/want 一样多的 FXML/controller 对。每个 FXML 文件都应该有自己的控制器 class。如果您想要它定义的 UI 的多个实例,您可以根据需要多次加载 FXML 文件:每次 FXMLLoader
都会为您创建一个与 [= 关联的新控制器实例105=] 你加载的元素。
Application
子class(你叫它Main
)代表了整个应用。每个应用程序应该只有一个这样的 class,并且只有一个实例,它是由 FX 工具包为您创建的。
当您启动 FX 应用程序(我将在下面描述)时,FX 工具包也会启动。然后你的 Application
subclass 的一个实例被创建,它的 init()
方法被调用(如果你没有定义一个,默认实现什么也不做)。然后启动 FX 应用程序线程,并在该线程上调用 Application
subclass 实例的 start()
方法。
您的 start()
方法应该只做很少的工作。通常它会加载您的 "main" fxml 文件,将生成的 UI 放在场景中,将场景放在舞台上,然后显示舞台。所有逻辑都将由 FXML 文件的控制器处理,而不是 Application
subclass.
在更高级的应用程序中,您可能会启动一些后台服务 and/or 在您的 init()
方法中创建一些数据模型,并在 start()
方法中将它们与控制器连接,但是上面的想法是基础。
实际的启动过程可以通过几种方式发生。如果您使用的是标准 Oracle JRE,则启动 Application
subclass with
java Main
(where Main extends Application
) 将导致上述过程发生;换句话说,FX 工具包启动,创建 Main
的实例,调用其 init()
方法,并在 FX 应用程序线程上调用其 start()
方法。
其他环境(尤其是 IDE)不知道 JavaFX 启动过程,并期望您正在执行的 class 有一个 public static void main(String[] args)
方法,就像任何标准 Java申请class。为了支持这些环境,您的 Application
subclass 定义一个 main(...)
方法是很常见的,它只调用 launch(...)
(从 Application
继承的静态方法) . launch
方法强制 FX 工具包启动等。它在任何应用程序生命周期内只能调用一次。
所以现在你有这样的东西:
package com.example ;
// imports...
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// just load fxml file and display it in the stage:
FXMLLoader loader = new FXMLLoader(getClass().getResource("mainUI.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
// main method to support non-JavaFX-aware environments:
public static void main(String[] args) {
// starts the FX toolkit, instantiates this class,
// and calls start(...) on the FX Application thread:
launch(args);
}
}
那么你会得到 mainUI.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import java.util.ArrayList?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.MyController">
<Label fx:id="label1"/>
<Label fx:id="label2"/>
</VBox>
和控制器
package com.example ;
// imports...
public class MyController {
@FXML
private Label label1 ;
@FXML
private Label label2 ;
// called by the FXML loader after the labels declared above are injected:
public void initialize() {
// do initialization and configuration work...
// trivial example, could also be done directly in the fxml:
label1.setText("Foo");
label2.setText("Bar");
}
}