JavaFX:在实例化控制器类时传递参数 [英] JavaFX : Pass parameters while instantiating controller class

查看:1110
本文介绍了JavaFX:在实例化控制器类时传递参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究JavaFX应用程序。我的所有gui都是 .fxml 格式,并通过控制器类管理所有GUI组件。但是,在加载FXML加载器之前,我在 实例化控制器类 时遇到了困难。我无法在stackoverflow上找到其他人的问题的好解决方案,因此这不是一个重复的问题。

I am working on JavaFX application right now. All my gui is in .fxml format and through controller class manages all GUI components. However, I have difficulties with instantiating the controller class before I load FXML loader. I was unable to find a good solution for my question from others on stackoverflow, therefore this is not a duplicate question.

我实例化控制器类的原因是我想 传递一些参数 ,以便这些参数将显示在GUI中。

The reason why I am instantiating the controller class is that I want to pass some parameters so that these parameters will be displayed in GUI.

我正在加载FXML提交以下方式:

I am loading an FXML file the following way:

/*
 * for Work Order button
 */
@FXML
private void pressWorkOrder() throws Exception{ 
    WorkOrderController wo = new WorkOrderController("ashdkjhsahd");    //instantiating constructor     

    Parent parent = FXMLLoader.load(getClass().getResource("/fxml/WorkOrder.fxml"));        
    Scene scene = new Scene(parent);
    Stage stage = new Stage();
    stage.setScene(scene);
    stage.setTitle("Word Order");
    stage.setResizable(false);
    stage.show();
}

这是我的实际控制器类:

And here is my actual Controller class:

public class WorkOrderController implements Initializable{

     @FXML
     private Button summary;
     private String m,n;

     public WorkOrderController(String str) {
         // TODO Auto-generated constructor stub
         m = str;
     }  

     //for testing
     public void set(String str){
         m = str;
     }  

     @FXML
     public void check(){
         System.out.println("Output after constructor was initialized " + m);
     }

     @Override
     public void initialize(URL location, ResourceBundle resources) {
        // TODO Auto-generated method stub
     }
 }

我得到这个例外:

at javafx.fxml.FXMLLoader.processStartElement(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.loadImpl(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at MainController.pressWorkOrder(MainController.java:78)
... 57 more
Caused by: java.lang.InstantiationException: WorkOrderController
at java.lang.Class.newInstance(Unknown Source)
at sun.reflect.misc.ReflectUtil.newInstance(Unknown Source)
... 71 more
Caused by: java.lang.NoSuchMethodException: WorkOrderController.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
... 73 more


推荐答案

为小型应用程序执行此操作的两种最简单方法是:

The two easiest ways of doing it for small applications are :


  1. 不要指定 fx: fxml中的controller 。通过向其传递数据来创建控制器实例,然后将其传递给FXMLLoader。

  1. Do not specify the fx:controller in the fxml. Create a controller instance by passing data to it and then pass it to the FXMLLoader.

指定 fx:controller 在fxml中。从FXMLLoader获取控制器实例并将数据传递给控制器​​。

Specify the fx:controller in the fxml. Fetch the controller instance from the FXMLLoader and pass the data to the controller.

以下是两个示例以上所述类型。每个示例都有3个组件:

The following are the examples for both the above said types. Each of the example have 3 components :


  • FXML - FXML文件,没有第一种类型的 fx:controller 声明,并将其用于第二种类型。

  • 控制器 - 有一个<第一种类型的code>构造函数。第二种类型的 setter方法

  • Main - 用于加载FXML并将数据传递给控制器​​。对于第一种情况,将控制器设置为FXMLLoader 。在第二个时,从FXMLLoader 获取控制器。

  • FXML - The FXML file, which doesn't have the fx:controller declaration for the first type and has it for the second type.
  • Controller - Has a constructor for the first type. Has setter methods for the second type.
  • Main - Used for loading FXML and pass data to the controller. For first case, it sets the controller to FXMLLoader. While in second, it fetches the controller from the FXMLLoader.

FXML - 不要指定fx:controller

FXML - Do not specify the fx:controller

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.control.Label?>

<FlowPane fx:id="root" xmlns:fx="http://javafx.com/fxml">
    <children>
        <Label fx:id="firstName" text="" />
        <Label fx:id="lastName" text="" />
    </children>
</FlowPane>

控制器 - 创建一个构造函数以接受默认值

Controller - create a Constructor to accept default values

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

import java.net.URL;
import java.util.ResourceBundle;

public class SampleController implements Initializable {

    private StringProperty firstNameString = new SimpleStringProperty();
    private StringProperty lastNameString = new SimpleStringProperty();

    /**
     * Accepts the firstName, lastName and stores them to specific instance variables
     * 
     * @param firstName
     * @param lastName
     */
    public SampleController(String firstName, String lastName) {
        firstNameString.set(firstName);
        lastNameString.set(lastName);
    }

    @FXML
    Label firstName;

    @FXML
    Label lastName;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        firstName.setText(firstNameString.get());
        lastName.setText(lastNameString.get());
    }
}

Main - 创建一个控制器实例,通过将值传递给它,然后将其传递给FXMLLoader

Main - Create a Controller instance, by passing value into it and then pass it to the FXMLLoader

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Sample.fxml"));

        // Create a controller instance
        SampleController controller = new SampleController("itachi", "uchiha");
        // Set it in the FXMLLoader
        loader.setController(controller);
        FlowPane flowPane = loader.load();
        Scene scene = new Scene(flowPane, 200, 200);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}






2。从FXMLLoader获取控制器实例



FXML - 已指定fx:controller


2. Fetch a controller instance from FXMLLoader

FXML - Has specified the fx:controller

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.control.Label?>

<!-- Controller Specified -->
<FlowPane fx:id="root" xmlns:fx="http://javafx.com/fxml" fx:controller="SampleController">
    <children>
        <Label fx:id="firstName" text="" />
        <Label fx:id="lastName" text="" />
    </children>
</FlowPane>

控制器 - 具有接受输入的Setter方法

Controller - Has Setter methods to accept input

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

import java.net.URL;
import java.util.ResourceBundle;

public class SampleController implements Initializable {

    @FXML
    Label firstName;

    @FXML
    Label lastName;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

    }

    /**
     * Accepts a String and sets it to the firstName Label
     *
     * @param firstNameString
     */
    public void setFirstName(String firstNameString) {
        firstName.setText(firstNameString);
    }

    /**
     * Accepts a String and sets it to the lastName Label
     *
     * @param lastNameString
     */
    public void setLastName(String lastNameString) {
        lastName.setText(lastNameString);
    }
}

主要 - 获取调用 load()后调用FXMLLoader中的控制器实例,然后调用setter方法传递数据。

Main - Fetches the Controller instance from FXMLLoader after calling the load() and then calls the setter methods to pass data.

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Sample.fxml"));
        FlowPane flowPane = loader.load();
        // Get the Controller from the FXMLLoader
        SampleController controller = loader.getController();
        // Set data in the controller
        controller.setFirstName("itachi");
        controller.setLastName("uchiha");
        Scene scene = new Scene(flowPane, 200, 200);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这篇关于JavaFX:在实例化控制器类时传递参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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