微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么当字段被声明为超类型时 FXMLLoader 不初始化字段

如何解决为什么当字段被声明为超类型时 FXMLLoader 不初始化字段

当我声明如下所示的外地球员时:

class Controller{
    @FXML Shape player;
}

.fxml 文件 - <Rectangle fx:id="player" ...\>
Controller 中,player 被声明为超类型 (Shape),而在 fxml 文件中 它被声明为子类型。

我将播放器声明为 Shape,而不是 Rectangle,因为我有多个类似的 fxml 文件,并且程序在运行时决定加载哪个文件。每个 fxml 文件都有一个 Shape

子类的播放器对象

我的问题是,当一个字段被声明为超类型时,fxml 加载器不会初始化该字段。我想知道解决此问题的方法

最小可重复示例:

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;

public class test2 extends Application {
    @FXML Shape player;
    public void start(Stage stage) throws Exception
    {
        Scene scene = new Scene(
                FXMLLoader.load(getClass().getResource("t.fxml"))
        );
        stage.setTitle("JavaFX Example");
        stage.setScene(scene);
        stage.show();
        System.out.println(player); //prints null
    }
    public static void main (String [] args){
        launch(args);
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.Pane?>
<?import javafx.scene.shape.Rectangle?>
<Pane xmlns:fx="http://javafx.com/fxml" prefheight="400.0" prefWidth="600.0">
    <Rectangle fx:id="player" x="20" y="20" width="40" height="40"/>
</Pane>

解决方法

@FXML 注释的字段在控制器中初始化。通常要创建控制器,您在 FXML 的根元素中指定一个 fx:controller 属性(尽管还有其他方法可以做到这一点)。您的 test2 类 [原文如此] 不是控制器类(即使是,调用 start() 的实例也不是控制器)。

对您的代码进行的以下修改表明,声明为超类类型的字段确实按照您的预期进行了初始化:

Controller.java:

package org.jamesd.examples.supertype;

import javafx.fxml.FXML;
import javafx.scene.shape.Shape;

public class Controller{
    @FXML Shape player;
    
    public void initialize() {
        System.out.println(player);
    }
}

t.fxml(注意 fx:controller 属性):

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

<?import javafx.scene.layout.Pane?>
<?import javafx.scene.shape.Rectangle?>
<Pane xmlns:fx="http://javafx.com/fxml" prefHeight="400.0"
    prefWidth="600.0"
    fx:controller="org.jamesd.examples.supertype.Controller">
    <Rectangle fx:id="player" x="20" y="20" width="40" height="40" />
</Pane>

Test2.java:

package org.jamesd.examples.supertype;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;

public class Test2 extends Application {
    @FXML Shape player;
    public void start(Stage stage) throws Exception
    {
        Scene scene = new Scene(
                FXMLLoader.load(getClass().getResource("t.fxml"))
        );
        stage.setTitle("JavaFX Example");
        stage.setScene(scene);
        stage.show();
    }
    public static void main (String [] args){
        launch(args);
    }
}

这会生成预期的输出:

Rectangle[id=player,x=20.0,y=20.0,width=40.0,height=40.0,fill=0x000000ff]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。