java - 如何将 FX Controller 与主应用程序连接

标签 java user-interface model-view-controller javafx fxml

我有一个主要的应用程序类和一个 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

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();请有人解释一下

最佳答案

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

虽然你说你“知道 FXMLLoader”,但如果你完全理解,你实际上会理解你问的其他一些事情,所以:

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

  • 加载 FXML 文件
  • 创建由 fx:controller 指定的 Controller 类的实例属性,通过调用其无参数构造函数
  • 设置任何 @FXML 的值- 将 Controller 中的注释字段添加到使用匹配 fx:id 定义的元素中属性
  • 注册映射到 Controller 中方法的任何事件处理程序
  • 调用 initialize() Controller 上的方法(如果有)。

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

    您可以根据需要/希望在应用程序中拥有任意数量的 FXML/ Controller 对。每个 FXML 文件都应该有自己的 Controller 类。如果您想要它定义的多个 UI 实例,您可以根据需要多次加载 FXML 文件:每次 FXMLLoader将为您创建一个与您加载的 UI 元素相关联的新 Controller 实例。
    Application子类(您称之为 Main )代表整个应用程序。每个应用程序应该只有一个这样的类和它的一个实例,它是由 FX 工具包为您创建的。

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

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

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

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

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

    其他环境(尤其是 IDE)不知道 JavaFX 启动过程,并且期望您正在执行的类具有 public static void main(String[] args)方法,就像任何标准的 Java 应用程序类一样。为了支持这些环境,您的 Application 很常见。定义 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>
    

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

    关于java - 如何将 FX Controller 与主应用程序连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33881046/

    相关文章:

    python - Django 注册备选方案

    android - Dojo/jQuery Mobile/等如何融入移动应用程序

    python - 如何控制 tkinter 按钮小部件上图像和文本之间的空间?

    c++ - 为 QML 的 ListView 公开 QObjects 的 QAbstractListModel。好的做法?

    java - 是什么让框架成为 "true"MVC 框架?

    java - SQL 语句应该返回 2 行,但只返回 1 行

    java - 再次使用 Eclipse Jetty 的 Maven 插件的 NoClassDef-s

    css - css 中的 MVC 内容文件夹 url 在本地主机和生产服务器之间呈现不相同

    java - 平移/旋转/移动图形对象而不弄乱整个屏幕

    java - 重复相同的异常堆栈跟踪