0

i have tried all solution in youtube and google but none of them work. The problem is when i want to switch to new scene along sending data to another scene i got error saying

Null pointer Exception

public class FirstController implements Initializable {

    @FXML private TextField textField;
    @FXML private Button btn;
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub
    }

    public void  onClick(ActionEvent event){
        //switching to new scene
        FXMLLoader loader=new FXMLLoader();
        loader.setLocation(getClass().getResource("/application/Second.fxml"));
        try{
            loader.load();
        }catch(Exception e){ }
        SecondController sn=loader.getController();
        sn.setText(textField.getText());
        Parent p=loader.getRoot();  
        Stage window=new Stage();
        window.setScene(new Scene(p));
        window.setTitle("dfd");
        window.show();
    }
}

main.fxml:

<AnchorPane prefHeight="450.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Main">
   <children>
      <Button fx:id="btn" layoutX="285.0" layoutY="264.0" mnemonicParsing="false" onAction="#onClick" text="Button" />
      <TextField fx:id="textField" layoutX="237.0" layoutY="213.0" />
   </children>
</AnchorPane>

Second controller :

public class SecondController implements Initializable {

    @FXML private Label labelField;
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub  
    }

    public void setText(String name){
        this.labelField.setText(name);
    } 
}

Second.fxml:

`<AnchorPane prefHeight="450.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label fx:id="labelField" layoutX="297.0" layoutY="208.0" text="Label" />
   </children>

    </AnchorPane>
  • you can try to create a static variable – Elarbi Mohamed Aymen Apr 17 '18 at 15:58
  • So I'm just gonna throw in a little suggestion for you. I've had all kinds of trouble with Initializable and the "initialize" method. What I ended up doing was building my own controller and extending it on all pages. I usually just have a "start" method that I call to initialize the view. Shouldn't get any null pointers that way. – Philip Vaughn Apr 17 '18 at 16:15
  • @ElarbiMohamedAymen can you provide me full code – Manjil Nepali Apr 17 '18 at 16:29
  • @ElarbiMohamedAymen That will not work: see https://stackoverflow.com/q/23105433/. Anyway, what would happen if you loaded the FXML more than once? You would have multiple labels, but only one reference to them, so there would be no way of knowing which label's text you were changing. – James_D Apr 17 '18 at 16:31
  • @PhilipVaughn But he's not using the `initialize()` method in either controller. Not sure how this is relevant...? – James_D Apr 17 '18 at 16:32
  • 1
    Don't squash exceptions. Print the stack trace and include the complete stack trace in the question. (What is null? Is it `labelField`, or `textField`, or something else?) Post the fxml files in the question as well. – James_D Apr 17 '18 at 16:34
  • @James_D for his case it will work – Elarbi Mohamed Aymen Apr 17 '18 at 16:36
  • please anyone provide me solid solution for this problem?? – Manjil Nepali Apr 17 '18 at 16:55
  • Your first FXML has `fx:controller="application.Main"` but the first controller class you show is called `FirstController`. What's the actual code you have tested? – James_D Apr 17 '18 at 16:59
  • @James_D i fixed that but again it shows same problem – Manjil Nepali Apr 17 '18 at 17:05
  • Yes: the controller you get from the loader is null. See answer. – James_D Apr 17 '18 at 17:06
  • 1
    @ManjilNepali You should never simply ignore a exception if it makes the code that follows fail. If `loader.load()` fails all the remaining code od the `onClick` method runs into problems any you don't provide any clue on why this happens. If you don't want to add a `throws` clause you should log the exception somewhere and not execute the rest of the code of the method. – fabian Apr 17 '18 at 23:18
  • Sorry @James_D for the delay. I guess I meant it more as a "stay away from the "implements Initializable" all together. I've never had much luck with it. Usually just create my own abstract controller to extend and everything works as intended. – Philip Vaughn Apr 18 '18 at 20:03
  • @PhilipVaughn You don't need to explicitly implement `Initializable`: you can just define an `initialize()` method and it will be invoked. That *always* works as advertised: I don't think it is at all good advice to recommend people to stay away from the intended use. – James_D Apr 18 '18 at 20:06
  • @James_D ya know what. I think you JUST told me why I was having weird errors. I was always calling the "initialize" method. So it was probably running twice. Didn't know it called it on its own. – Philip Vaughn Apr 18 '18 at 20:11

1 Answers1

0

Your second FXML file is missing the fx:controller attribute. Therefore, when you load it, there is no controller, and so loader.getController() returns null.

Consequently, when you call sn.setText(...), you get a null pointer exception.

Just add the missing fx:controller attribute to the second FXML file. Assuming that SecondController is in the application package, this will look like:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Label?>

<AnchorPane prefHeight="450.0" prefWidth="650.0" fx:controller="application.SecondController" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label fx:id="labelField" layoutX="297.0" layoutY="208.0" text="Label" />
   </children>

</AnchorPane>

Also note that it's very bad practice to silently "squash" exceptions, by using

try {
    /* ... */
} catch (Exception e) { }

It's especially bad if the ensuing code depends on the code in the try block succeeding. In particular, in this case if your call to load() results in an exception (which may happen for a multitude of reasons, including the FXML not being found or being invalid, the fx:id and field names, or types, not matching, method names for handlers not matching or having the wrong parameters, etc.), then the load method will silently fail and the controller will not be set in the loader. This will again result in sn being null.

Here's a complete example using your code, but with the other errors fixed as well as the missing fx:controller attribute inserted:

application/Main.java:

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(FXMLLoader.load(getClass().getResource("First.fxml")));
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

application/First.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>

<AnchorPane prefHeight="450.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.FirstController">
   <children>
      <Button fx:id="btn" layoutX="285.0" layoutY="264.0" mnemonicParsing="false" onAction="#onClick" text="Button" />
      <TextField fx:id="textField" layoutX="237.0" layoutY="213.0" />
   </children>
</AnchorPane>

application/FirstController.java:

package application;
import java.net.URL;
import java.util.ResourceBundle;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class FirstController implements Initializable {

    @FXML private TextField textField;
    @FXML private Button btn;
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub
    }

    public void  onClick(ActionEvent event) throws Exception {
        //switching to new scene
        FXMLLoader loader=new FXMLLoader();
        loader.setLocation(getClass().getResource("/application/Second.fxml"));
        loader.load();
        SecondController sn=loader.getController();
        sn.setText(textField.getText());
        Parent p=loader.getRoot();  
        Stage window=new Stage();
        window.setScene(new Scene(p));
        window.setTitle("dfd");
        window.show();
    }
}

application/Second.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Label?>

<AnchorPane prefHeight="450.0" prefWidth="650.0" fx:controller="application.SecondController" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label fx:id="labelField" layoutX="297.0" layoutY="208.0" text="Label" />
   </children>

</AnchorPane>

application/SecondController.java

package application;
import java.net.URL;
import java.util.ResourceBundle;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

public class SecondController implements Initializable {

    @FXML private Label labelField;
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub  
    }

    public void setText(String name){
        this.labelField.setText(name);
    } 
}
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException – Manjil Nepali Apr 17 '18 at 17:24
  • @ManjilNepali I copied and pasted your code, made the change to fix the name of the first controller, and made this change, and it works fine for me. That doesn't explain the actual error you are getting; what is the root cause of the exception, and what code is actually throwing it? – James_D Apr 17 '18 at 17:26