如何将fx控制器与主应用程序连接

我有一个主app类和一个fxmlcontroller类,但我纠结于连接/组织(混淆了如何调用它们以及如何组织它们以使GUI连接业务逻辑)业务逻辑和GUI ….可以请一些人告诉我调用以下函数的顺序,或者可以帮助我如何调用它们….

主要课程

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 launch(args); //please explain about it 

fxmlController类

 public void initialize() //I don't know what it is and what purpose it has public fxmlController() // which function should be called here.... NOTE: I know aboout FXMLLoader(); please someone explain 

我认为FXML文件及其相应的控制器是一对管理用户界面的。 在较大的应用程序中,您可能有几个这样的FXML控制器对,它们构成了用户界面的不同部分。 在每对中,FXML文件定义UI的布局,并且控制器定义逻辑(即,它通常处理用户输入等)。

虽然你说你“了解FXMLLoader ”,但如果你完全明白,你会真正了解你所询问的其他一些事情,所以:

FXML文件及其控制器定义的用户界面由FXMLLoader加载到内存中。 在最简单的设置中,控制器由FXML文件的根元素中的fx:controller属性定义。 在FXMLLoader上调用load()方法时,它:

  1. 加载FXML文件
  2. 通过调用其无参数构造函数,创建fx:controller属性指定的控制器类的实例
  3. 将控制器中任何@FXML字段的值设置为使用匹配的fx:id属性定义的元素
  4. 注册映射到控制器中的方法的任何事件处理程序
  5. 如果有的话,调用控制器上的initialize()方法。

注意那些事件的顺序:在注入@FXML -annotated字段之前调用构造函数,但之后调用initialize()方法。 这意味着您可以在initialize()方法中访问(和配置)和@FXML -annotated字段,但不能在构造函数中访问。 很常见(至少在简单的应用程序中)不在控制器类中定义任何构造函数,只是使用默认值。

您可以根据需要/需要在应用程序中使用尽可能多的FXML /控制器对。 每个FXML文件都应该有自己的控制器类。 如果你想要它定义的UI的多个实例,你可以根据需要多次加载FXML文件:每次FXMLLoader都会为你创建一个与你加载的UI元素相关联的新控制器实例。

Application子类(您将其称为Main )表示整个应用程序。 每个应用程序应该只有一个这样的类,并且只有一个实例,它是由FX工具包为您创建的。

当您启动FX应用程序(我将在下面描述)时,FX工具包将启动。 然后创建一个Application子类的实例,并调用其init()方法(如果没有定义一个,则默认实现不执行任何操作)。 然后启动FX应用程序线程,并在该线程上调用Application子类实例的start()方法。

你的start()方法应该做很少的工作。 通常,它会加载“主”fxml文件,将生成的UI放在场景中,将场景放在舞台上,然后显示舞台。 所有逻辑都将由控制器处理FXML文件,而不是由Application子类处理。

在更高级的应用程序中,您可以在init()方法中启动一些后台服务和/或创建一些数据模型,并在start()方法中将它们与控制器连接,但上面的想法是基础知识。

实际的启动过程可以通过几种方式实现。 如果您使用的是标准Oracle JRE,则启动Application子类

 java Main 

Main extends Application )将导致上述过程发生; 换句话说,启动FX工具包,创建Main的实例,调用其init()方法,并在FX Application Thread上调用它的start()方法。

其他环境(特别是IDE)不了解JavaFX启动过程,并且期望正在执行的类具有public static void main(String[] args)方法,就像任何标准Java应用程序类一样。 为了支持这些环境,您的Application子类通常会定义一个main(...)方法,该方法只调用launch(...) (从Applicationinheritance的静态方法)。 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:

         

和控制器

 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"); } } 

控制器绑定在您的fxml文件中,或者您第一次调用主视图。

因此,您可以使用xml中的fx:controller属性或启动器中的FXMLLoader#setController()方法。