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);
}
Axifive
  • 1,159
  • 2
  • 19
  • 31

1 Answers1

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")));
    }
}
Jai
  • 8,165
  • 2
  • 21
  • 52
  • 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. – Heman Kundu Feb 15 '18 at 07:13
  • @HemanKundu "I set one single controller for both FXMLs". No, that's not true - the `FXMLLoader` creates a new controller whenever you call `load()`. – James_D Feb 16 '18 at 11:37
  • 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? – Heman Kundu Feb 16 '18 at 20:07
  • @James_D Can you please help? – Heman Kundu Feb 18 '18 at 13:57
  • @HemanKundu Like I said, each FXML should have its own controller class. Mixing everything together just isn't the correct way to do it. – Jai Feb 20 '18 at 00:55