1

I'm trying to pass a String between scenes in JavaFX, I already followed the some answers but it seems that they don't work because the string is null in the new scene.

Here's my MainControler:

public class FXMLDocumentController implements Initializable {


    @FXML
    private Button btn_signup;
    @FXML
    private TextField et_username;
    @FXML
    private PasswordField et_password;
    @FXML
    private Hyperlink link_login;

    Stage prevStage;

    public void setPrevStage(Stage stage){
         this.prevStage = stage;
    }

    @FXML
    private void handleButtonAction(ActionEvent event) throws IOException {

        if(btn_signup == event.getSource()){
            Conector conn = new Conector();

        if (conn.checkUser(et_username.getText(), et_password.getText())) {
                    FXMLLoader myLoader = new FXMLLoader(getClass().getResource("FXMLTasker.fxml"));
                       Pane myPane = (Pane)myLoader.load();



                    Scene scene = new Scene(myPane);

                    Stage stage = new Stage();

                    stage.setResizable(false);
                    stage.setScene(scene);

                    FXMLTaskerController controler = new FXMLTaskerController();
                    controler.setUser(et_username.getText());
                    myLoader.setController(controler);
                    prevStage.close();
                    stage.show();
        }else {
            JOptionPane.showMessageDialog(null, "Usuario o Contraseña incorrecta");
        }

        }else if (link_login == event.getSource()){
            System.out.println("Registrate!");
        }


    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

}

Here's the other class controler, the one where i want my String.

public class FXMLTaskerController implements Initializable {


    @FXML private ListView list_todo;
    @FXML private ListView list_done;
     @FXML public String username;

    private void handleButtonAction(ActionEvent event) {


    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        System.out.println(username);
        list_todo.setCellFactory(new TaskCellFactory());
        list_done.setCellFactory(new TaskCellFactory());
        try {
            getTasks();
        } catch (IOException ex) {
            Logger.getLogger(FXMLTaskerController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }   



    public void setUser(String username){
        this.username = username;
    }

    public void getTasks() throws IOException{
        Conector con = new Conector();
        for(Task task: con.obtenerTareas("pepin")){
            System.out.println(task);
            if(task.isState()){
                list_done.getItems().add(task);
            }else{
                list_todo.getItems().add(task);
            }
        }
    }
}

And here are the fxml files:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane prefHeight="400.0" prefWidth="500.0" style="-fx-background-color: #0288D1; -fx-border-color: #01579B; -fx-border-width: 5;" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="desktop_tasker.FXMLDocumentController">
   <children>
      <Label layoutX="215.0" layoutY="34.0" text="Sign In" textFill="WHITE">
         <font>
            <Font size="23.0" />
         </font>
      </Label>
      <Hyperlink fx:id="link_login" layoutX="150.0" layoutY="269.0" onAction="#handleButtonAction" text="Not registered yet? Click here." textFill="WHITE" />
      <TextField fx:id="et_username" layoutX="21.0" layoutY="102.0" prefHeight="25.0" prefWidth="425.0" promptText="Username" style="-fx-prompt-text-fill: #ffffff; -fx-background-color: #0288D1;" />
      <Separator layoutX="27.0" layoutY="126.0" prefHeight="3.0" prefWidth="425.0" />
      <Separator layoutX="27.0" layoutY="192.0" prefHeight="3.0" prefWidth="425.0" />
      <Button fx:id="btn_signup" layoutX="27.0" layoutY="222.0" mnemonicParsing="false" onAction="#handleButtonAction" prefHeight="23.0" prefWidth="425.0" style="-fx-background-color: #FFA000; -fx-prompt-text-fill: #ffffff;" text="SignUp" textFill="WHITE" />
      <PasswordField fx:id="et_password" layoutX="21.0" layoutY="167.0" prefHeight="25.0" prefWidth="425.0" promptText="Password" style="-fx-background-color: #0288D1; -fx-prompt-text-fill: #ffffff;" />
   </children>
</AnchorPane>

And the other one:

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

<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="557.0" prefWidth="1012.0" style="-fx-background-color: #0288D1;" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="desktop_tasker.FXMLTaskerController">
   <children>
      <SplitPane dividerPositions="0.5811881188118811" layoutX="-8.0" layoutY="35.0" prefHeight="529.0" prefWidth="1027.0" style="-fx-background-color: #EEEEEE;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="28.0">
        <items>
            <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
               <children>
                  <ListView fx:id="list_todo" layoutY="-8.0" prefHeight="527.0" prefWidth="584.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
               </children>
            </AnchorPane>
          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
               <children>
                  <ListView fx:id="list_done" layoutY="14.0" prefHeight="527.0" prefWidth="420.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
               </children></AnchorPane>
        </items>
      </SplitPane>
      <MenuBar prefHeight="30.0" prefWidth="1012.0">
        <menus>
          <Menu mnemonicParsing="false" text="File">
            <items>
              <MenuItem mnemonicParsing="false" text="Close" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Edit">
            <items>
              <MenuItem mnemonicParsing="false" text="Delete" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Help">
            <items>
              <MenuItem mnemonicParsing="false" text="About" />
            </items>
          </Menu>
        </menus>
      </MenuBar>
   </children>
</AnchorPane>

As you can see I tried to use a controler and using a set pasing the String, the problem is that when I open the new scene, his controler resets and the String is no longer there, any idea why or how to solve this?

1 Answers1

0

If you want to set a Controller with myLoader.setController(controler); you must do it before calling Pane myPane = (Pane)myLoader.load(); and also remove fx:controller="desktop_tasker.FXMLTaskerController" from FXMLTasker.fxml, else you get a LoadException: Controller value already specified.

See JavaDoc FXMLLoader.setController(Object controller):

Sets the controller associated with the root object. The value passed to this method is used as the value of the fx:controller attribute. This method must be called prior to loading the document when using controller event handlers when an fx:controller attribute is not specified in the document.


Alternatively you can request the Controller from FXMLLoader:

 FXMLTaskerController controler = (FXMLTaskerController)myLoader.getController();
 controler.setUser(et_username.getText());

But thereby you can't assume that username is set in initialize(URL url, ResourceBundle rb) and should removed from there.