基本上我有一个方法将数据库从数据库加载到imageView中,第二种方法来更改图像我成功运行这两种方法而没有异常但是在changeImage()方法中的setImage之后我需要什么更新以及如何(场景,舞台)是否可能。我知道在javafx中没有类似repaint()的方法,所以我该如何处理呢?
public class MainMenuController implements Initializable {
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
private AnchorPane stck1;
@FXML
private AnchorPane openSecondWindow(ActionEvent event) throws Exception {
GUIController ctrl = new GUIController();
Stage stage = new Stage();
setStck1((AnchorPane) FXMLLoader.load(InteractiveFictionGame2.class.getResource("GUI.fxml")));
ImageView img_1 = new ImageView(ctrl.loadImg().getImage());
img_1.setPreserveRatio(true);
img_1.setSmooth(true);
img_1.setCache(true);
getStck1().getChildren().add(img_1);
Scene scene = new Scene(getStck1());
stage.setTitle("Interactive Fiction Game");
stage.setScene(scene);
stage.setFullScreen(true);
// stage.sizeToScene();
stage.show();
return getStck1();
}
public class GUIController implements Initializable {
@FXML
private TabPane tb1;
/**
* Initializes the controller class.
*
* @param url
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private ImageView img_1;
public ImageView loadImg() {
try {
con = DriverManager.getConnection(host, unm, pswrd);
stmnt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmnt.executeQuery(SQL);
rs.next();
fis = rs.getBinaryStream(4);
imgt = javax.imageio.ImageIO.read(fis);
Image newImg = SwingFXUtils.toFXImage(imgt, null);
img_1 = new ImageView();
img_1.setImage(newImg);
rs.close();
stmnt.close();
con.close();
} catch (Exception e) {
System.out.println("Not working");
}
return img_1;
}
public void changeImage() {
..
fis = rs.getBinaryStream(1);
imgt = javax.imageio.ImageIO.read(fis);
Image newImg = SwingFXUtils.toFXImage(imgt, null);
img_1.setImage(newImg);
...
} catch (Exception e) {
System.out.println("Not working");
}
return img_1;
}
答案 0 :(得分:11)
您的问题
如果控制器中有一个使用@FXML
注入的成员节点,则不应使用new
构造函数创建新对象实例,并将该新对象分配给现有引用。相反,只需使用为您创建FXML的对象。
你有:
@FXML
private ImageView img_1;
没关系。然后在loadImg中,你有:
img_1 = new ImageView();
img_1.setImage(newImg);
这很糟糕。在加载FXML文档时,您已经拥有了FXMLLoader为您创建的ImageView。然后,FXML Loader将ImageView分配给您的img_1
引用,因为您使用了@FXML
注释。
如何解决
所以你需要做的就是停止创建新的ImageViews并且只写:
img_1.setImage(newImg);
你完成了。
为什么会有效
ImageView的Image属性是一个可观察的属性。 JavaFX系统会观察Image属性以进行任何更改,如果更改,则会自动更新屏幕上显示的ImageView图像。你不需要执行任何重绘调用(在任何情况下都没有这样的重绘例程)。
背景阅读
如果您想更好地理解JavaFX场景图架构,请阅读上面的Oracle教程:
一些提示
<强>声明强>
除了此处指出的问题之外,您未提供的代码中可能还有其他错误,这可能会阻止您按照自己的意愿使应用程序正常工作。
答案 1 :(得分:0)
以下效果很好:
首先创建Image和ImageView实例:
Image imageObject = new Image();
ImageView imageViewObject = new ImageView();
然后在代码中按下一个按钮事件会导致(下一个)图像被分配和更新,如下所示:
btn.setOnAction(e -> {
imageIndex++;
imageFilename = imageNamesArray.get(imageIndex);
imageObject = new Image(imageFilename);
imageViewObject.setImage(imageObject);
}
注意:我的项目中的文件名是在ArrayList()中保存为String元素的jpg文件(名称)。单击按钮也会将数组索引增加到下一个jpg文件名(和路径或URL),然后会出现新图像。 因此,在上述答案中,您只创建一个ImageViewObject,但是您将新图像重新分配给图像对象&#34; imageObject&#34;每一次。