JavaFX ImageView not updating

后端 未结 1 1917
春和景丽
春和景丽 2021-01-17 07:16

So I\'m trying to load and save Images into an imageView where the location of the image is chosen through a file browser. I\'ve been working on this for several days now an

相关标签:
1条回答
  • 2021-01-17 08:05

    Two things:

    1. Never assign a field whose value is to be injected by an FXMLLoader (e.g. @FXML fields). Doing so is a waste of resources at best and introduces subtle bugs at worst. For instance, if you were to leave the imageView field uninitialized you'd be getting a NullPointerException which would indicate a problem with your setup. Since you do initialize the field, however, you don't get any errors and there's a false impression of the code working.

    2. In your RootLayout controller class, you have:

      private Controller controller = new Controller();
      

      That instance of Controller you just created is not linked to any FXML file. And since you initialize the imageView field (see first point) you end up updating an ImageView which is not being displayed anywhere; this is where not initializing said field would have given a nice indication of there being a problem. The solution is to pass the Controller instance created by the FXMLLoader to the RootLayout instance created by the other FXMLLoader.

      Also, in the same class you have:

      Main main = new Main();
      

      Which is also unnecessary since the created instance of Main is both not the correct instance and is replaced by the call to #setMain(Main) almost immediately.


    Assuming your FXML files (which you did not provide) are correct, the Java classes should look more like:

    Main.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);
      }
    }
    

    RootLayout.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());
        }
      }
    }
    

    Controller.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) {}
    }
    

    Note: Did not test new code.

    0 讨论(0)
提交回复
热议问题