繁体   English   中英

JavaFX ImageView 未更新

[英]JavaFX ImageView not updating

所以我试图将图像加载并保存到 imageView 中,其中通过文件浏览器选择图像的位置。 我已经为此工作了好几天了,如果我不能把它修好,我就会中风。 我已经尝试了所有我能想到的。 预先感谢您的帮助。

更新

这是我的主要课程:

public class Main extends Application {
    private Stage primaryStage;
    private BorderPane rootLayout;
    public Main(){}
    @Override
    public void start(Stage primaryStage) throws Exception{
      this.primaryStage = primaryStage;
      this.primaryStage.setTitle("Help Please");
      initRootLayout();
      showScreen();
    }
    public void initRootLayout(){
        try{
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(Main.class.getResource("view/RootLayout.fxml"));
            rootLayout = (BorderPane) loader.load();
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            RootLayout controller = loader.getController();
            controller.setMain(this);
            primaryStage.show();
        }catch(Exception e ){e.printStackTrace();}
    }
    public void showScreen(){
        try{FXMLLoader loader = new FXMLLoader();
        loader.setLocation(Main.class.getResource("view/sample.fxml"));
        BorderPane sample = (BorderPane)loader.load();
        rootLayout.setCenter(sample);
        Controller controller = loader.getController();
        controller.setMain(this);
        }catch (Exception e){e.printStackTrace();}
    }
    public Stage getPrimaryStage(){return primaryStage;}
    public static void main(String[] args) {
        launch(args);
    }
}

这是根布局:

public class RootLayout {
    private Main main;
    private Controller controller = new Controller();
    public void setMain(Main main){this.main = main;}
    @FXML
    private void handleOpen(){
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter(
                "PNG files (*.png)","*png");
        fileChooser.getExtensionFilters().add(extensionFilter);
        File file = fileChooser.showOpenDialog(main.getPrimaryStage());
        if(file!= null){
            controller.updateImage(file.toURI().toString());
        }
    }
}

这是控制器:

public class Controller implements Initializable {
    @FXML
    ImageView imageView = new ImageView();
    String imageURL;
    Main main = new Main();
    public void setMain(Main main){
        this.main = main;
    }
    public void updateImage(String url){
        if(url.length()>=1){
            Image image = new Image(url);
            imageView.setImage(image);
            System.out.println(url);
        }
        else{
            System.out.println(url);
            System.out.println("image invalid");
        }
    }
    @Override
    public void initialize(URL location, ResourceBundle resources) {
    }
}

两件事情:

  1. 切勿分配其值将由FXMLLoader注入的FXMLLoader (例如@FXML字段)。 这样做充其量是浪费资源,最糟糕的是会引入微妙的错误。 例如,如果您未初始化imageView字段,则会收到NullPointerException ,这表明您的设置存在问题。 但是,由于您确实初始化了该字段,因此您不会收到任何错误,并且对代码工作有一种错误的印象。

  2. 在您的RootLayout控制器类中,您有:

     private Controller controller = new Controller();

    您刚刚创建的那个Controller实例没有链接到任何 FXML 文件。 并且由于您初始化了imageView字段(请参阅第一点),因此您最终会更新未在任何地方显示的ImageView 这是不初始化所述字段会很好地表明存在问题的地方。 解决方案是将FXMLLoader创建的Controller实例FXMLLoader给另一个FXMLLoader创建的RootLayout实例。

    此外,在同一个班级中,您有:

     Main main = new Main();

    这也是不必要的,因为创建的Main实例既不是正确的实例,又几乎立即被调用#setMain(Main)替换。


假设您的 FXML 文件(您没有提供)是正确的,Java 类应该看起来更像:

主程序

public class Main extends Application {

  private Stage primaryStage;
  private BorderPane rootLayout;
  private RootLayout rootLayoutController;

  public Main() {}

  @Override
  public void start(Stage primaryStage) throws Exception {
    this.primaryStage = primaryStage;
    this.primaryStage.setTitle("Help Please");
    initRootLayout();
    showScreen();
  }

  public void initRootLayout() {
    try {
      FXMLLoader loader = new FXMLLoader();
      loader.setLocation(Main.class.getResource("view/RootLayout.fxml"));
      rootLayout = (BorderPane) loader.load();
      Scene scene = new Scene(rootLayout);
      primaryStage.setScene(scene);

      // store RootLayout instance in field so #showScreen()
      // can reference it
      rootLayoutController = loader.getController();
      rootLayoutController.setMain(this);

      primaryStage.show();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void showScreen() {
    try {
      FXMLLoader loader = new FXMLLoader();
      loader.setLocation(Main.class.getResource("view/sample.fxml"));
      BorderPane sample = (BorderPane) loader.load();
      rootLayout.setCenter(sample);
      Controller controller = loader.getController();
      controller.setMain(this);

      // set Controller instance on RootLayout instance
      rootLayoutController.setController(controller);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public Stage getPrimaryStage() {
    return primaryStage;
  }

  public static void main(String[] args) {
    launch(args);
  }
}

根布局.java

public class RootLayout {

  private Main main;
  private Controller controller;

  public void setMain(Main main) {
    this.main = main;
  }

  public void setController(Controller controller) {
    this.controller = controller;
  }

  @FXML
  private void handleOpen() {
    FileChooser fileChooser = new FileChooser();
    // Note extensions should be prefixed with "*."
    FileChooser.ExtensionFilter extensionFilter =
        new FileChooser.ExtensionFilter("PNG files (*.png)", "*.png");
    fileChooser.getExtensionFilters().add(extensionFilter);
    File file = fileChooser.showOpenDialog(main.getPrimaryStage());
    if (file != null) {
      controller.updateImage(file.toURI().toString());
    }
  }
}

控制器.java

public class Controller implements Initializable {

  @FXML ImageView imageView; // leave uninitialized, will be injected
  String imageURL;
  Main main;

  public void setMain(Main main) {
    this.main = main;
  }

  public void updateImage(String url) {
    if (url.length() >= 1) {
      Image image = new Image(url);
      imageView.setImage(image);
      System.out.println(url);
    } else {
      System.out.println(url);
      System.out.println("image invalid");
    }
  }

  @Override
  public void initialize(URL location, ResourceBundle resources) {}
}

注意:没有测试新代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM