gpt4 book ai didi

javafx - JavaFX:在实例化 Controller 类时传递参数

转载 作者:行者123 更新时间:2023-12-03 10:08:44 25 4
gpt4 key购买 nike

我现在正在研究JavaFX应用程序。我的所有GUI都是.fxml格式,并且通过 Controller 类管理所有GUI组件。但是,在加载FXML加载程序之前,我很难用实例化 Controller 类。我无法从其他关于stackoverflow的问题中找到一个好的解决方案,因此这不是重复的问题。

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

我通过以下方式加载FXML文件:

/*
* 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();
}

这是我实际的Controller类:
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

最佳答案

对于小型应用程序,最简单的两种方法是:

  • 不要在fxml中指定fx:controller。通过将数据传递给它来创建一个 Controller 实例,然后将其传递给FXMLLoader。
  • 在fxml中指定fx:controller。从FXMLLoader获取 Controller 实例,然后将数据传递给 Controller ​​。

  • 以下是上述两种类型的示例。每个示例都有3个组成部分:
  • FXML-FXML文件,它对第一种类型的doesn't have声明进行fx:controller,对第二种类型进行声明。
  • Controller -第一种类型具有constructor。第二种类型具有setter methods
  • Main-用于加载FXML并将数据传递到 Controller 。对于第一种情况,它为sets the controller to FXMLLoader。在第二秒,它是fetches the controller from the FXMLLoader


  • 1.手动创建 Controller 实例

    FXML -不指定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 -创建一个构造函数以接受默认值
    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());
    }
    }

    -创建一个Controller实例,方法是将值传递给它,然后将其传递给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获取 Controller 实例

    FXML -已指定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>

    Controller -具有Setter方法来接受输入
    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获取Controller实例,然后调用setter方法以传递数据。
    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 - JavaFX:在实例化 Controller 类时传递参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30814258/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com