JavaFX更改imageView中的图像 [英] JavaFX change the image in an imageView

查看:727
本文介绍了JavaFX更改imageView中的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我有一个方法可以将数据库中的图像加载到imageView中,还有第二种方法来更改图像,我成功地运行了这两个方法而没有异常,但是在changeImage()方法中的setImage之后,我需要做什么?更新,以及如何(场景,阶段).我知道在javafx中没有像repaint()这样的方法,那么我该如何处理呢?

Basically I have a method to load an Image from database into an imageView and a second method to change the image I'm sucessfully running both methods without getting an exception but after the setImage in changeImage() method what do I need to update and how (scene,stage) is it possible at all. I know that there is no method like repaint() in swing in javafx, so how do I approach this ?

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;
    }

推荐答案

您的问题

如果在控制器中使用@FXML进行注入的成员节点,则永远不要使用new构造函数创建新的对象实例,并将该新对象分配给现有引用.而是只使用FXML为您创建的对象.

If you have a member node in your controller which you inject using @FXML, you should never create a new object instance using a new constructor and assign that new object to your existing reference. Instead just use the object which FXML created for you.

您有:

@FXML
private ImageView img_1;

很好.

然后在loadImg中,您拥有:

Then in loadImg, you have:

img_1 = new ImageView();
img_1.setImage(newImg);

那很糟糕.

您已经有一个ImageView,它是在加载FXML文档时FXMLLoader为您创建的.然后,由于您使用了@FXML批注,因此FXML Loader将该ImageView分配给了img_1引用.

You already have an ImageView which the FXMLLoader created for you when you loaded your FXML document. The FXML Loader then assigned that ImageView to your img_1 reference because you used an @FXML annotation.

如何修复

所以您要做的就是停止创建新的ImageView,而只写:

So all you need to do is to stop creating new ImageViews and only write:

img_1.setImage(newImg);

您完成了.

为什么起作用

ImageView的Image属性是一个可观察的属性. JavaFX系统观察Image属性是否发生任何更改,如果更改,则会自动更新ImageView屏幕上显示的图像.您不需要执行任何重画调用(在任何情况下都没有这样的重画例程可以调用).

The Image property of ImageView is an observable property. The JavaFX system observes the Image property for any changes and if it changes, automatically updates the image displayed on the screen for the ImageView. You don't need to perform any repaint call (there is no such repaint routine to call in any case).

背景知识

如果您想更好地理解JavaFX场景图架构,请阅读有关它的Oracle教程:

If you want to understand the JavaFX scene graph architecture better, read the Oracle tutorial on it:

一些提示

  • 您可以任务与数据库进行通信,您的应用程序可能会响应更快.
  • 从文件或通过http而不是从数据库中读取图像可能更简单.
  • You can create a JavaFX image directly from an InputStream, you don't need to use ImageIO and SwingFXUtils for this task.
  • You can use a Task to communicate with a database and your application may be more responsive.
  • It is probably simpler to read the image from a file or over http rather than from a database.

免责声明

除了此处指出的问题外,您可能没有提供其他代码错误,这些错误可能会阻止您使应用程序按需运行.

Besides the issue pointed out here, there may be other errors in code you have not provided which may prevent you from getting your application to work as you wish.

这篇关于JavaFX更改imageView中的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆