JavaFX在imageView中更改图像

Kyl*_*ern 4 graphics javafx image scene

基本上我有一个方法将数据从数据库加载到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;
    }
Run Code Online (Sandbox Code Playgroud)

jew*_*sea 12

你的问题

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

你有:

@FXML
private ImageView img_1;
Run Code Online (Sandbox Code Playgroud)

没关系.然后在loadImg中,你有:

img_1 = new ImageView();
img_1.setImage(newImg);
Run Code Online (Sandbox Code Playgroud)

那很不好.在加载FXML文档时,您已经拥有了FXMLLoader为您创建的ImageView.然后,FXML Loader将ImageView分配给您的img_1引用,因为您使用了@FXML注释.

如何解决它

所以你需要做的就是停止创建新的ImageViews并且只写:

img_1.setImage(newImg);
Run Code Online (Sandbox Code Playgroud)

你完成了.

为什么会这样

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

背景阅读

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

一些技巧

  • 您可以直接从InputStream创建JavaFX映像,您不需要使用ImageIO和SwingFXUtils来完成此任务.
  • 您可以使用任务与数据库进行通信,并且您的应用程序可能响应更快.
  • 从文件或http而不是从数据库读取图像可能更简单.

放弃

除了此处指出的问题之外,您未提供的代码中可能存在其他错误,这可能会阻止您按照自己的意愿使应用程序正常工作.