【问题标题】:JavaFX change the image in an imageViewJavaFX 更改 imageView 中的图像
【发布时间】:2015-04-07 20:31:32
【问题描述】:

基本上,我有一种方法可以将数据库中的图像加载到 imageView 中,还有第二种方法可以更改图像我成功地运行了这两种方法而没有出现异常,但是在 changeImage() 方法中的 setImage 之后我需要做什么更新以及(场景,舞台)如何可能。我知道 javafx 中的 swing 中没有像 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;
    }

【问题讨论】:

    标签: image graphics javafx scene


    【解决方案1】:

    您的问题

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

    你有:

    @FXML
    private ImageView img_1;
    

    没关系。

    然后在 loadImg 中,你有:

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

    这很糟糕。

    当您加载 FXML 文档时,您已经有一个 FXMLLoader 为您创建的 ImageView。然后,FXML 加载器将该 ImageView 分配给您的 img_1 引用,因为您使用了 @FXML 注释。

    如何解决

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

    img_1.setImage(newImg);
    

    你就完成了。

    为什么会起作用

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

    背景阅读

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

    一些提示

    • 你可以create a JavaFX image directly from an InputStream,你不需要使用 ImageIO 和 SwingFXUtils 来完成这个任务。
    • 您可以使用Task 与数据库进行通信,您的应用程序可能会响应更快。
    • 从文件或通过 http 而不是从数据库读取图像可能更简单。

    免责声明

    除了此处指出的问题外,您未提供的代码中可能还存在其他错误,这可能会阻止您的应用程序按您的意愿运行。

    【讨论】:

      【解决方案2】:

      Java 我在这里毕业:
      在我的 JavaFX 术语项目中,我必须在 setOnAction 事件(单击按钮)时更新 imageView 对象。这允许程序用户点击一系列图片。

      以下效果很好:
      首先创建你的 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() 中的字符串元素的 jpg 文件(名称)。单击按钮还会将数组索引增加到下一个 jpg 文件名(和路径或 URL),并且会出现新图像。 因此,在上述答案中,您只创建一个 ImageViewObject,但每次都会将新图像重新分配给图像对象“imageObject”。

      【讨论】:

      • 这个问题已经在 4 月份得到了全面解答,我在这个答案中看不到任何新内容。实际上,您的代码示例有点误导,因为没有理由用空图像初始化 imageObject。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      相关资源
      最近更新 更多