[英]Why does FXMLLoader not initialize fields when a field is declared as a super-type
When I declare a field player as shown below:当我声明一个外场球员时,如下所示:
class Controller{
@FXML Shape player;
}
.fxml file - <Rectangle fx:id="player"...\>
.fxml 文件 -
<Rectangle fx:id="player"...\>
Where in the Controller
, player
is declared as a super type ( Shape
), and in the fxml file it is declared as a subtype.在
Controller
中, player
被声明为超类型( Shape
),而在 fxml 文件中,它被声明为子类型。
I declare player as Shape
, instead of Rectangle
, because I have multiple similar fxml files, and the program decides, during runtime, which one to load.我将 player 声明为
Shape
而不是Rectangle
,因为我有多个类似的 fxml 文件,并且程序在运行时决定加载哪个文件。 Every fxml file has a player object of some child class of Shape
每个fxml文件都有
Shape
的某子class的播放器object
My problem is that when a field is declared as the super type, fxml loader doesn't initialize that field.我的问题是,当一个字段被声明为超类型时,fxml 加载器不会初始化该字段。 I would like to know a work-around to this problem.
我想知道这个问题的解决方法。
A minimum reproducible example:一个最小可重现的例子:
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
-annotated fields are initialized in the controller. @FXML
字段在 controller 中初始化。 Typically to create controllers, you specify a fx:controller
attribute in the root element of the FXML (though there are other ways to do this).通常,要创建控制器,您需要在 FXML 的根元素中指定
fx:controller
属性(尽管还有其他方法可以做到这一点)。 Your test2
class [sic] is not the controller class (and even if it were, the instance on which start()
is invoked would not be the controller).您的
test2
class [原文如此] 不是 controller class (即使是,调用start()
的实例也不会是控制器)。
The following modification of your code demonstrates that fields declared as a superclass type are indeed initialized as you would expect:您的代码的以下修改表明声明为超类类型的字段确实按照您的预期进行了初始化:
Controller.java: 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 (note fx:controller
attribute): 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:测试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);
}
}
This generates the expected output:这会生成预期的 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.