Search code examples
javafxnullpointerexceptionfxmlimage-viewer

How to load image in ImageView dynamically in Java FX


I'm working with FXML and have two different Scene on a single Stage. btnStart is on scene1, and imgBtn is on scene2. When I click btnStart it sets scene2 to stage and loads an image to imageView (this is throwing NullPointerException). But when I click imgBtn on scene2 it is loading image.

My question is how to load image dynamically when I switch to scene2 ?

@FXML private Button imgBtn;
@FXML private Button btnStart;
@FXML public ImageView imageView;

@FXML
public void imgBtnClicked()throws Exception{      
    imageView.setImage(new Image(new FileInputStream("src/Assets/CardAssets/png-v2/3C.png")));
}


@FXML
public void btnStartClicked()throws Exception{
    SetScene2();
    imageView.setImage(new Image(new FileInputStream("src/Assets/CardAssets/png-v2/3C.png")));

}  

public void SetScene2()throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource(fxmlFile2.fxml));
    String css=getClass().getResource("myStyle.css").toExternalForm();
    Scene scene;
    try{
        scene=new Scene(root,root.getScene().getWidth(),root.getScene().getHeight());
    }
    catch(NullPointerException e) {
        scene=new Scene(root,stage.getWidth(),stage.getHeight());
    }
    scene.getStylesheets().add(css);
    stage.setScene(scene);
}

Solution

  • The question is not exactly very clear, so I'm going to make some guesses here. The most likely problem is that you have confused which Nodes are on which scene which is on which controller.

    The correct structure for this is that you have two sets of each of the following items:

    1. FXML file
    2. Controller class
    3. Scene object.

    This is how it should be done:

    public class ControllerA {
        @FXML private Button btnStart;
    
        @FXML
        public void btnStartClicked()throws Exception{
            setScene2();
        }  
    
        public void setScene2()throws Exception {
            // You may need to set the controller to an instance of ControllerB,
            // depending whether you have done so on the FXML.
            Parent root = FXMLLoader.load(getClass().getResource(fxmlFile2.fxml));
    
            String css=getClass().getResource("myStyle.css").toExternalForm();
            Scene scene;
            try{
                scene=new Scene(root,root.getScene().getWidth(),root.getScene().getHeight());
            }
            catch(NullPointerException e) {
                scene=new Scene(root,stage.getWidth(),stage.getHeight());
            }
            scene.getStylesheets().add(css);
            stage.setScene(scene);
        }
    
    }
    
    public class ControllerB {
        @FXML private ImageView imageView;
        @FXML private Button imgBtn;
    
        @FXML public void initialize() {
            imageView.setImage(new Image(new FileInputStream("src/Assets/CardAssets/png-v2/3C.png")));
        }
    
        @FXML
        public void imgBtnClicked()throws Exception{      
            imageView.setImage(new Image(new FileInputStream("src/Assets/CardAssets/png-v2/3C.png")));
        }
    }