0

I got a question about passing a selected date from DatePicker to another FXML file. I’ve seen code in similar threads but I can’t seem to get my head around it.

Basically I want to select a date from DatePicker (in DiscountController) and be able to retrieve that selected date in another FXML file(in ConfirmController) and print it. Here is what I go so far.

Can anyone tell what I’m doing wrong/missing here?

public class DiscountController implements Initializable {

    private final static DiscountController instance = new DiscountController();
    public static DiscountController getInstance() {
        return instance;
    }


    @FXML private DatePicker dp;
    @FXML private Label lblDate;

    public DatePicker getDp() {
        return dp;
    }


    //button to print the selected date in a label. This works fine
    @FXML private void ConfirmBtnAction (ActionEvent event) {
          lblDate.setText(dp.getValue().toString());
          }


  //button to move to next FXML screen
  @FXML private void nextBtnAction(ActionEvent event) {

    try{
     Parent parent = FXMLLoader.load(getClass().getResource("/appl/Confirm.fxml"));
     Stage stage = new Stage();
     Scene scene = new Scene(parent);
     stage.setScene(scene);
     stage.show();


     }
     catch(IOException e){
     }
}
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }    

}

the fxml file

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

<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ivikappl.DiscountController">
  <children>
    <Label contentDisplay="LEFT" layoutX="236.0" layoutY="33.0" prefHeight="42.0" prefWidth="133.0" text="Discount">
      <font>
        <Font size="28.0" />
      </font>
    </Label>
    <Button fx:id="btnNext" layoutX="525.0" layoutY="358.0" mnemonicParsing="false" onAction="#nextBtnAction" prefWidth="61.0" text="Next" />
    <Label layoutX="231.0" layoutY="158.0" prefHeight="21.0" prefWidth="69.0" text="Select Date" />
    <Label layoutX="404.0" layoutY="158.0" prefHeight="21.0" prefWidth="101.0" text="Select discount %" />
    <Label layoutX="54.0" layoutY="158.0" prefHeight="21.0" prefWidth="69.0" text="Product" />
      <DatePicker fx:id="dp" layoutX="189.0" layoutY="117.0" />
      <Label fx:id="lblDate" layoutX="219.0" layoutY="247.0" prefHeight="35.0" prefWidth="95.0" />
      <Button fx:id="btnConfirm" layoutX="241.0" layoutY="200.0" mnemonicParsing="false" onAction="#ConfirmBtnAction" text="Confirm" />
      <TextField layoutX="391.0" layoutY="117.0" />
      <Label fx:id="lblProduct" layoutX="22.0" layoutY="121.0" prefHeight="17.0" prefWidth="149.0" />
        </children>
</AnchorPane>

ConfirmController file

public class ConfirmController implements Initializable  {


//button to fetch selected date from DiscountController and print it 
//Having a problem, here, this one doesn't work
@FXML private void btnFetchAction (ActionEvent event) {
   String A;
    A = DiscountController.getInstance().getDp().getValue().toString();
            System.out.println(A);
      }


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

}

and the FXML

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

<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ivikappl.ConfirmController">
   <children>
      <Button layoutX="382.0" layoutY="74.0" mnemonicParsing="false" prefHeight="49.0" prefWidth="115.0" text="Generate barcode" textAlignment="CENTER" />
      <Label layoutX="91.0" layoutY="31.0" prefHeight="30.0" prefWidth="79.0" text="Summary">
         <font>
            <Font name="System Bold" size="12.0" />
         </font>
      </Label>
      <Label layoutX="40.0" layoutY="123.0" prefHeight="20.0" prefWidth="85.0" text="Productname">
         <font>
            <Font name="System Italic" size="12.0" />
         </font>
      </Label>
      <Label fx:id="lblDate" layoutX="40.0" layoutY="79.0" prefHeight="20.0" prefWidth="67.0">
         <font>
            <Font name="System Italic" size="12.0" />
         </font>
      </Label>
      <Label layoutX="40.0" layoutY="166.0" prefHeight="20.0" prefWidth="67.0" text="Discount">
         <font>
            <Font name="System Italic" size="12.0" />
         </font>
      </Label>
      <Button fx:id="btnFetch" layoutX="40.0" layoutY="236.0" mnemonicParsing="false" onAction="#btnFetchAction" text="Fetch" />
   </children>
</AnchorPane>
Ophichius
  • 17
  • 4

1 Answers1

1

You can't use the singleton pattern here because the FXMLLoader essentially creates an instance of DiscountController by calling the no-argument constructor (i.e. not by calling DiscountController.getInstance()). (You could go this route if you really wanted, by setting a controller factory on the FXMLLoader that loaded the discount FXML file, but it really doesn't make sense for controllers to be singletons. In many cases you really need multiple instances of them. And there are much simpler ways to achieve what you are trying to do anyway.)

Define a method in ConfirmController to which you can pass the date:

public class ConfirmController {

    @FXML
    private Label lblDate ;

    public void setDate(LocalDate date) {
        lblDate.setText(date.toString());
    }

    // ... other code as before...
}

and then just call it when you load the FXML:

public class DiscountController implements Initializable {

    @FXML private DatePicker dp;

    // ...

    @FXML private void nextBtnAction(ActionEvent event) {

        try{
         FXMLLoader loader = new FXMLLoader(getClass().getResource("/appl/Confirm.fxml"));
         Parent parent = loader.load();
         ConfirmController confirmController = loader.getController();
         confirmController.setDate(dp.getValue());
         Stage stage = new Stage();
         Scene scene = new Scene(parent);
         stage.setScene(scene);
         stage.show();


         }
         catch(IOException e){
         }
    }

    // ...
}

See Passing Parameters JavaFX FXML for a bunch of other ways to do this.

Community
  • 1
  • 1
James_D
  • 201,275
  • 16
  • 291
  • 322