簡體   English   中英

為什么當字段聲明為超類型時,FXMLLoader 不初始化字段

[英]Why does FXMLLoader not initialize fields when a field is declared as a super-type

當我聲明一個外場球員時,如下所示:

class Controller{
    @FXML Shape player;
}

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

我將 player 聲明為Shape而不是Rectangle ,因為我有多個類似的 fxml 文件,並且程序在運行時決定加載哪個文件。 每個fxml文件都有Shape的某子class的播放器object

我的問題是,當一個字段被聲明為超類型時,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字段在 controller 中初始化。 通常,要創建控制器,您需要在 FXML 的根元素中指定fx:controller屬性(盡管還有其他方法可以做到這一點)。 您的test2 class [原文如此] 不是 controller class (即使是,調用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>

測試2.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);
    }
}

這會生成預期的 output:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM