JavaFX:在实例化控制器类时传递参数 [英] JavaFX : Pass parameters while instantiating controller class
问题描述
我正在研究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 :
-
不要指定
fx: fxml中的controller
。通过向其传递数据来创建控制器实例,然后将其传递给FXMLLoader。
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
thefx:controller
declaration for the first type and has it for the second type. - Controller - Has a
constructor
for the first type. Hassetter 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, itfetches 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屋!