0

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

1 Answer 1

2

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")));
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Actually I set one single controller for both FXML 's. I am new to this type of programming, I have one array in that controller class containing some cards whose image is to be loaded to scene2's imageView. And from scene1 I'm generating the content of the array.
@HemanKundu "I set one single controller for both FXMLs". No, that's not true - the FXMLLoader creates a new controller whenever you call load().
Thank you for responding, but in both FXML files, I have set fx:controller="HeartsApp" . So that I can access an array from both the scenes as mentioned. Is there any alternative way to doing it?
@James_D Can you please help?
@HemanKundu Like I said, each FXML should have its own controller class. Mixing everything together just isn't the correct way to do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.