【问题标题】:Change/Update FXML components in another class更改/更新另一个类中的 FXML 组件
【发布时间】:2016-07-02 08:28:17
【问题描述】:

我的问题是:我想从 .fxml 中更改一些内容,但无论我做什么,都没有任何改变。这只是一个简单的例子。

我浏览了整个互联网,但没有一个解决方案适合我。 这里我想通过在主类中调用相应的方法来更改标签的文本。

单击按钮时调用相同的方法(此处为setLabel()),使用控制器类中的事件处理程序,一切正常,但是当我尝试从另一个类修改某些内容时,没有任何作用。

主类:

package sample;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;  
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

@Override
public void start(Stage primaryStage) throws Exception{

Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
Controller controller = new Controller();
Platform.runLater(()->controller.setLabel());

}

FXML 代码:

<BorderPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <center>
      <Label fx:id="label" text="This" BorderPane.alignment="CENTER" />
   </center>
</BorderPane>

控制器类: 包装样品;

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

public class Controller {
@FXML
private Label label=new Label();

public void setLabel(){
    label.setText("Test");
}
}

【问题讨论】:

    标签: java javafx controller label fxml


    【解决方案1】:

    您的代码实际上存在两个问题。

    1)Applicationstart 方法中,您使用FXMLLoader 加载sample.fxml,这是正确的。但是创建一个像Controller controller = new Controller();这样的新控制器是不正确的,因为你应该使用getController方法从FXMLLoader本身获取控制器,并且你不应该使用FXMLLoader的静态load函数,但是你应该创建它的一个实例。

    FXMLLoader loader = new FXMLLoader();
    Parent root = loader.load(getClass().getResource("sample.fxml"));
    Controller controller = loader.getController();
    

    当您在 FXMLLoader 上调用 load 时,它将从 FXML 文件加载对象层次结构,并且还将创建一个控制器(在 FXML 文件中引用)。

    2)Controller 中,您从FXML 文件中注入Label,但您重新创建它。当FXMLLoader 基于fx:id 向控制器注入控件时,它还确保初始化。如果您创建一个新的Label,它将不会指向加载程序创建的Label 实例。

    这个

    @FXML private Label label=  new Label();
    

    应该替换为

    @FXML private Label label;
    

    【讨论】:

    • 谢谢,这比我发现的其他任何东西都更有帮助。 :)
    【解决方案2】:

    这很简单...您可以通过在 Controller 类中为所需标签添加 getter 方法来更改 Main 类中的标签文本,然后使用控制器对象(loader.xml)在 Main 类中获取它。 getController()) 并更新其文本。或者使用 Main 中的控制器对象调用 Controller 类中的 setter 方法。 正如 DVagra 所说,使用 loader.getController() 来获取控制器对象。 (其中 loader 是 FXMLoader 的对象)。

    此外,您不需要 Platform.runLater() 来更新 gui 控件。因为您已经在 FX 线程上运行了。

    不管怎样,这就是你需要的。

    主类

    package sample;
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(Main.class.getResource("sample.fxml"));
        Parent root = loader.load();
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    
        Controller controller = loader.getController();
    
        controller.setLabel("Test");
    //  Or
    //  controller.getLabel().setText("Test");
     }
    public static void main(String[] args) {
        launch(args);
     }
    }
    

    控制器类

    package sample;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Label;
    import java.net.URL;
    import java.util.ResourceBundle;
    
    public class Controller implements Initializable{
    @FXML
    Label label;
    
    //setter
    public void setLabel(String labelText){
        label.setText(labelText);
    }
    
    //getter for label
    public Label getLabel() {
        return label;
    }
    
    @Override
    public void initialize(URL location, ResourceBundle resources) {
     }
    }
    

    Sample.fxml

    <?xml version="1.0" encoding="UTF-8"?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.layout.BorderPane?>
    
    <BorderPane xmlns="http://javafx.com/javafx/8.0.60" 
    xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
    <center>
        <Label fx:id="label" text="This" BorderPane.alignment="CENTER" />
    </center>
    </BorderPane>
    

    【讨论】:

    • 在我的“真实”项目中,我无法调用 setter 方法。我总是给我一个空指针执行。我似乎没有用 ... = loader.getController(); 初始化控制器;
    • 你是如何获得加载器对象的?请发布代码sn-p。
    • 我调用这个方法有点太早了,现在一切正常,再次感谢你,我被这个问题困扰了几天
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多