为什么 setImage() 不会更改我在 JavaFx 中的 ImgView?

why setImage() doesn't change my ImgView in JavaFx?

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.TilePane;
import javafx.stage.Stage;

public class ChooseScheme extends Application{

    GUIBoard board = new GUIBoard();
    Stage primaryStage;
    Integer totalScheme = 26;

//these are the imgs I want to change, in the fxml file they have their own path but with the method chooseRandomImgs(), 

    @FXML
    ImageView scheme1 = new ImageView();

    @FXML
    ImageView scheme2 = new ImageView();

    @FXML
    ImageView scheme3 = new ImageView();

    @FXML
    ImageView scheme4 = new ImageView();

    public void launchChooseScheme() throws Exception {

        start(new Stage());
    }

//standard method, it runs and open the scene

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

        this.primaryStage = primaryStage;
        Parent ChooseScheme;
        ChooseScheme = FXMLLoader.load(getClass().getClassLoader().getResource("GUIFiles/ChooseScheme.fxml"));

        Stage stage = new Stage();

        chooseRandomImgs();

        stage.setTitle("Choose Scheme");
        stage.setScene(new Scene(sgChooseScheme, 600, 400));
        stage.show();

    }

//this method should change my img

    private void chooseRandomImgs() {
        int countImages = totalScheme;
        int imageNumber = (int) (Math.random() * countImages);

        System.out.println(imageNumber);
        Image schemeImage = new Image("GUIfiles/imgs/schemecard/val5/"+ imageNumber + ".jpg");

        scheme1.setImage(schemeImage);
    }
}

img路径正确。当我 运行 class 不改变 ImgView scheme1;相反,它仍然是我在 SceneBuilder 上设置的 Img,每次我 运行 代码都不会显示新的 Img。我不明白为什么。

ChooseScheme 的实例与用于 fxml 的实例不同(假设 fx:controller 属性设置为适当的值)。

您始终初始化 ImageView 字段,但如果 ChooseScheme 的实例未与 fxml 一起使用,则这些实例永远不会添加到场景中。 (事实上​​ ,初始化程序创建的实例永远不会添加到场景中,但对于与 fxml 一起使用的控制器,初始值会在加载期间被替换。)

初始化应该从 fxml 注入的字段从来都不是一个好主意。这只是修复了可能抛出的NullPointerException

使用 Application class 作为控制器也不是一个好主意。

根据您想确定随机图像的位置,您需要使用此处介绍的方法之一 Passing Parameters JavaFX FXML

或者,您可以通过控制器的 initialize 方法执行此操作。此方法在 load 期间 运行 所有对象都已注入后。

例子

控制器class

package mypackage;

...

public ChooseSchemeController {

    private static final Random random = new Random();
    private static final int TOTAL_SCHEME = 26; // you don't want to use a wrapper type here

    @FXML
    private ImageView scheme1;

    @FXML
    private void initialize() {
        chooseRandomImage(scheme1);
    }

    private void chooseRandomImage(ImageView iv) {
        int imageNumber = random.nextInt(TOTAL_SCHEME);

        System.out.println(imageNumber);
        Image schemeImage = new Image("GUIfiles/imgs/schemecard/val5/"+ imageNumber + ".jpg");

        iv.setImage(schemeImage);
    }

}

GUIFiles/ChooseScheme.fxml

<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="mypackage.ChooseSchemeController">
    <children>
        <ImageView fx:id="scheme1"/>
    </children>
</VBox>