为什么 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>
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>