如何将 FX 控制器与主应用程序连接 [英] How to connect FX controller with main app

查看:32
本文介绍了如何将 FX 控制器与主应用程序连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个主要的应用程序类和一个 fxmlController 类,但我纠结于连接/组织(困惑如何调用它们以及我应该如何组织它们以制作 GUI 连接的业务逻辑)业务逻辑和 GUI.有人可以告诉我调用以下函数的顺序吗,或者任何人都可以帮助我如何调用它们?

I have a main app class and a fxmlController class but I am entangled in connecting/organizing(confused how these are called and how I should organize them to make the GUI connected business logic) business logic and GUI. Can someone please tell the order in which following function are called or can anyone help how I should call them?

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 类:

public void initialize()  //I don't know what it is and what purpose it has
public fxmlController()   // which function should be called here....

注意:我知道 FXMLLoader(); 请有人解释一下

NOTE: I know about FXMLLoader(); please someone explain

推荐答案

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

I think of an FXML file and its corresponding controller as a pair that manage the user interface. In larger applications you might have several such FXML-controller pairs that make up different parts of the user interface. Within each pair, the FXML file defines the layout of the UI, and the controller defines the logic (i.e. it typically processes user input, etc).

虽然您说您了解 FXMLLoader",但如果您完全理解这一点,您实际上会理解您询问的其他一些问题,因此:

While you said you "know about FXMLLoader", if you understand that fully you would actually understand some of the other things you asked about, so:

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

The user interface defined by an FXML file and its controller is loaded into memory by an FXMLLoader. In the simplest setup, the controller is defined by a fx:controller attribute in the root element of the FXML file. When the load() method is called on the FXMLLoader, it:

  1. 加载 FXML 文件
  2. 通过调用其无参数构造函数,创建由 fx:controller 属性指定的控制器类的实例
  3. 将控制器中任何 @FXML 注释字段的值设置为使用匹配的 fx:id 属性定义的元素
  4. 注册映射到控制器中方法的任何事件处理程序
  5. 调用控制器上的 initialize() 方法(如果有).
  1. Loads the FXML file
  2. Creates an instance of the controller class specified by the fx:controller attribute, by calling its no-argument constructor
  3. Sets the value of any @FXML-annotated fields in the controller to the elements defined with matching fx:id attributes
  4. Registers any event handlers mapping to methods in the controller
  5. Calls the initialize() method on the controller, if there is one.

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

Notice the order of those events: the constructor is called before the @FXML-annotated fields are injected, but the initialize() method is called after. This means you can access (and configure) and @FXML-annotated fields in the initialize() method, but not in the constructor. It is quite common (at least in simple applications) not to define any constructor in the controller classes and just to use the default.

您可以根据需要/希望在应用程序中拥有任意数量的 FXML/控制器对.每个 FXML 文件都应该有自己的控制器类.如果您想要它定义的 UI 的多个实例,您可以根据需要多次加载 FXML 文件:每次 FXMLLoader 都会为您创建一个与您的 UI 元素关联的新控制器实例已加载.

You can have as many FXML/controller pairs in your application as you need/want. Each FXML file should have its own controller class. You can load an FXML file as many times as you need if you want multiple instances of the UI it defines: each time the FXMLLoader will create a new controller instance for you that is associated with the UI element you loaded.

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

The Application subclass (you called it Main) represents the entire application. You should have only one such class per application and only one instance of it, which is created for you by the FX toolkit.

当您启动 FX 应用程序(我将在下面描述)时,FX 工具包就会启动.然后你的 Application 子类的一个实例被创建,它的 init() 方法被调用(如果你没有定义一个,默认实现什么都不做).然后启动 FX 应用程序线程,并在该线程上调用 Application 子类实例的 start() 方法.

When you start a FX application (which I'll describe below), the FX toolkit is started. Then an instance of your Application subclass is created, and its init() method is called (if you don't define one, the default implementation does nothing). The FX Application Thread is then started and the Application subclass instance's start() method is called on that thread.

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

Your start() method should do pretty minimal work. Typically it will load your "main" fxml file, place the resulting UI in a scene, put the scene in the stage, and show the stage. All the logic will be handled by the controller for the FXML file, not by the Application subclass.

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

In more advanced applications, you might start some background services and/or create some data models in your init() method, and connect them with the controller in the start() method, but the ideas above are the basics.

实际的启动过程可以通过多种方式进行.如果您使用的是标准 Oracle JRE,则使用

The actual startup process can happen in a couple of ways. If you are using the standard Oracle JRE, then launching an Application subclass with

java Main

(其中Main extends Application)会导致上面的过程发生;换句话说,FX 工具包被启动,一个 Main 的实例被创建,它的 init() 方法被调用,它是 start()方法在 FX 应用线程上调用.

(where Main extends Application) will cause the process above to happen; in other words the FX toolkit is started, an instance of Main is created, its init() method is called, and it's start() method is called on the FX Application Thread.

其他环境(尤其是 IDE)不知道 JavaFX 启动过程,并期望您正在执行的类具有 public static void main(String[] args) 方法,就像任何标准一样Java 应用程序类.为了支持这些环境,您的 Application 子类通常定义一个 main(...) 方法,该方法只需调用 launch(...)(继承自 Application 的静态方法).launch 方法强制 FX 工具包启动等.它只能在任何应用程序生命周期内调用一次.

Other environments (particularly IDEs) are not aware of the JavaFX startup process, and expect the class you are executing to have a public static void main(String[] args) method, like any standard Java application class. To support these environments, it is common for your Application subclass to define a main(...) method which simply calls launch(...) (a static method inherited from Application). The launch method forces the FX toolkit to start, etc. It can only be called once during any application lifetime.

所以现在你有类似的东西:

So now you have something like:

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:

Then you would have 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");
    }
}

这篇关于如何将 FX 控制器与主应用程序连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆