-1

What I have been trying to Achieve is an JavaFX application that computes the cost of the items selected through various categories which in the case are just two: Pizzas and Burgers.

When I click on button with text 'pizzas' on it the pizzas.fxml file is loaded where I select an item and thus the variable pizzatotal is incremented and then i come back to the main page. Till this step the value of variable Pizzatotal remains the same as the incremented value it was changed to. But as soon as I click on the button 'Burgers' from the main page the value of variable pizzatotal resets to 0.

I want the value of variable Pizzatotal to remain throughout my navigation between scenes in the application.

I built a total of 3 fxml files. One for the main Page which contains two buttons to navigate to the second and third page respectively.

This is the fxml code for the Main Page :

"'

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="- 
Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" 
xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" 
fx:controller="com.example.demo.HelloController">
<children>
  <Button layoutX="32.0" layoutY="34.0" mnemonicParsing="false" onAction="#switchtoOrderpage" prefHeight="71.0" prefWidth="114.0" text="Pizzas" />
  <Button layoutX="166.0" layoutY="34.0" mnemonicParsing="false" onAction="#switchtoburger" prefHeight="71.0" prefWidth="114.0" text="Burgers" />
</children>
</AnchorPane>

The second FXML file contains a grid pane with buttons to execute different methods. Frankly speaking every button on this screen adds the cost of pizza selected to the variable : total.

The code for the second FXML file is as follows:

"'

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>

<GridPane hgap="50.0" maxHeight="-Infinity" maxWidth="-Infinity" 
 minHeight="-Infinity" minWidth="-Infinity" prefHeight="1080.0" 
 prefWidth="1922.0" vgap="20.0" xmlns="http://javafx.com/javafx/17" 
 xmlns:fx="http://javafx.com/fxml/1" 
 fx:controller="com.example.demo.PizzaController">
 <columnConstraints>
 <ColumnConstraints hgrow="SOMETIMES" maxWidth="348.1999786376953" 
 minWidth="10.0" prefWidth="297.0000274658203" />
 <ColumnConstraints hgrow="SOMETIMES" maxWidth="433.80001220703133" 
 minWidth="0.0" prefWidth="298.7999633789062" />
 <ColumnConstraints hgrow="SOMETIMES" maxWidth="456.0" minWidth="0.0" 
 prefWidth="314.99990234375" />
 <ColumnConstraints hgrow="SOMETIMES" maxWidth="698.4000122070313" 
 minWidth="10.0" prefWidth="296.39997558593745" />
 <ColumnConstraints hgrow="SOMETIMES" maxWidth="939.8000610351562" 
 minWidth="10.0" prefWidth="282.20002441406245" />
 <ColumnConstraints hgrow="SOMETIMES" maxWidth="939.8000610351562" 
 minWidth="10.0" prefWidth="281.800048828125" />
 </columnConstraints>
 <rowConstraints>
 <RowConstraints maxHeight="238.39998779296874" minHeight="10.0" 
  prefHeight="238.39998779296874" vgrow="SOMETIMES" />
 <RowConstraints maxHeight="188.80000000000004" minHeight="0.0" 
  prefHeight="47.800012207031244" vgrow="SOMETIMES" />
 <RowConstraints maxHeight="312.80000000000007" minHeight="10.0" 
  prefHeight="228.60000000000002" vgrow="SOMETIMES" />
 <RowConstraints maxHeight="312.80000000000007" minHeight="0.0" 
  prefHeight="52.999987792968795" vgrow="SOMETIMES" />
 <RowConstraints maxHeight="494.6000122070312" 
  minHeight="3.5999755859375" prefHeight="262.79998779296875" 
  vgrow="SOMETIMES" />
 <RowConstraints maxHeight="480.8000122070313" minHeight="10.0" 
  prefHeight="158.00001220703132" vgrow="SOMETIMES" />
  </rowConstraints>
  <children>
  <Button fx:id="pizza" mnemonicParsing="false" onAction="#addpizza" 
  prefHeight="54.0" prefWidth="301.0" text="Paneer Pizza" 
  GridPane.rowIndex="1" />
  <Button fx:id="addMargherita" mnemonicParsing="false" 
  prefHeight="56.0" prefWidth="298.0" text="Margherita Pizza" 
  GridPane.columnIndex="1" GridPane.rowIndex="1" />
  <Button fx:id="pizza1" mnemonicParsing="false" prefHeight="54.0" 
  prefWidth="301.0" text="Chicken Pizza" GridPane.rowIndex="3" />
  <Button fx:id="pizza2" mnemonicParsing="false" prefHeight="54.0" 
  prefWidth="301.0" text="Cheese Burst" GridPane.columnIndex="1" GridPane.rowIndex="3" />
  <Button mnemonicParsing="false" prefHeight="49.0" prefWidth="358.0" text="Chilli Pizza" GridPane.columnIndex="2" GridPane.rowIndex="1" />
  <Button fx:id="gotomain" mnemonicParsing="false" onAction="#switchtomainpagefromPizza" prefHeight="157.0" prefWidth="266.0" text="Main page" GridPane.columnIndex="5" GridPane.rowIndex="5" />
  <Button layoutX="645.0" layoutY="584.0" mnemonicParsing="false" prefHeight="49.0" prefWidth="358.0" text="Pan Pizza" GridPane.columnIndex="3" GridPane.rowIndex="3" />
  <Button mnemonicParsing="false" prefHeight="62.0" prefWidth="395.0" text="Sicilian Pizza" GridPane.columnIndex="3" GridPane.rowIndex="1" />
  <Button mnemonicParsing="false" prefHeight="47.0" prefWidth="286.0" text="Chicago-Style Pizza" GridPane.columnIndex="4" GridPane.rowIndex="1" />
  <Button mnemonicParsing="false" prefHeight="66.0" prefWidth="266.0" text="New York - Style Pizza" GridPane.columnIndex="5" GridPane.rowIndex="1" />
  <Button fx:id="pizza21" mnemonicParsing="false" prefHeight="54.0" prefWidth="301.0" text="Hawaiian Pizza" GridPane.columnIndex="2" GridPane.rowIndex="3" />
  <Button layoutX="1022.0" layoutY="584.0" mnemonicParsing="false" prefHeight="49.0" prefWidth="358.0" text="Greek Pizza" GridPane.columnIndex="4" GridPane.rowIndex="3" />
  <Button mnemonicParsing="false" prefHeight="49.0" prefWidth="358.0" text="Crust Pizza" GridPane.columnIndex="2" GridPane.rowIndex="5" />
  <Button mnemonicParsing="false" prefHeight="49.0" prefWidth="358.0" text="Momo Pizza" GridPane.columnIndex="1" GridPane.rowIndex="5" />
  <Button mnemonicParsing="false" prefHeight="49.0" prefWidth="358.0" text="Corn Pizza" GridPane.columnIndex="5" GridPane.rowIndex="3" />
  <Button mnemonicParsing="false" prefHeight="49.0" prefWidth="358.0" text="Prime Pizza" GridPane.rowIndex="5" />
  <Button fx:id="pizza3" mnemonicParsing="false" prefHeight="54.0" prefWidth="301.0" text="Sauce Pizza" GridPane.columnIndex="3" GridPane.rowIndex="5" />
  <Button fx:id="pizza4" mnemonicParsing="false" prefHeight="54.0" prefWidth="301.0" text="Oregano Pizza" GridPane.columnIndex="4" GridPane.rowIndex="5" />
  </children>
  </GridPane>

'"

The third FXML file is also exactly similar to this hence I'm not including the code to it to cut it short.

I have built 3 diff controller classes to control the Main-page, the pizzas page and the Burgers page.

The controller class for the main-page is as follows:

"'
public class HelloController extends PizzaController{

public void switchtopizzapage(ActionEvent event) throws IOException {
    Parent root = FXMLLoader.load(getClass().getResource("pizzas.fxml"));
    Stage stage = (Stage) (((Node) event.getSource()).getScene().getWindow());
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.setFullScreen(false);
    stage.setHeight(400);stage.setWidth(600);
    stage.show();
}


public  void switchtoburger(ActionEvent event) throws IOException {
    Parent root = FXMLLoader.load(HelloController.class.getResource("Burgers.fxml"));
    Stage stage = (Stage) (((Node) event.getSource()).getScene().getWindow());
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.setFullScreen(false);
    System.out.println(total);
    stage.show();
}

}'"

The method 'switchtopizzapage' opens the pizza page which is the second FXML scene and the 'switchtoburger' opens the third FXML scene.

The main page looks like this:

This is the main-page.

The controller class for the pizzas.fxml file is given below:

public class PizzaController {

public  int total;



public void addpizza(){
    int pizzaCost = 100;
    total = total + pizzaCost;
    System.out.println(total);
}


public void switchtomainpagefromPizza(ActionEvent event) throws IOException {
    Parent root = FXMLLoader.load(getClass().getResource("Main-Page.fxml"));
    Stage stage = (Stage) (((Node) event.getSource()).getScene().getWindow());
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.setFullScreen(false);
    System.out.println(total);
    stage.show();
}

}

The controller class for the Burgers.fxml is given below:

public class BurgerController extends PizzaController{



public  void addChickenBurger(){
    int ChickenBurgerCost = 100;
   total = total+ ChickenBurgerCost;
   System.out.println(total);


}
public  void switchtomainpagefromBurger(ActionEvent event) throws IOException {
    Parent root = FXMLLoader.load(getClass().getResource("Main-Page.fxml"));
    Stage stage = (Stage) (((Node) event.getSource()).getScene().getWindow());
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.setFullScreen(false);
    stage.show();
}

}

kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • When dealing with variables created in the `FXML` file, `Button gottomainfromburger = new Button()` in the `Controller` is a no-no. It should be `@FXML Button gottomainfromburger;` Other than that, you should look into [`MCV`](https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx). If you use ideas from @James_D answer, that should fix your issue of when changing scenes. – SedJ601 Jan 23 '22 at 05:51
  • @Sedrick Thanks for the tip but the variables I am talking about are the int variables which are pizzatotal etc. – Antazya Singh Jatrana Jan 23 '22 at 06:29
  • 2
    Create a [mre] and edit your question to include it. There are so many things wrong in the code you've posted, but it's not complete enough to know which are causing the problems you observe. This is not really answerable as posted. – James_D Jan 23 '22 at 07:22
  • @James_D I have edited the post to much extent and included text to explain the issue I have been facing. Please help me with this issue I have been stuck for two days on this single thing only. – Antazya Singh Jatrana Jan 23 '22 at 10:05
  • 2
    please re-read the comment by @James_D, study the referenced help page thoroughly and act accoringly: your code is not reproducible - missing the application - and only near (though not far away) to minimal - containing unrelated fluff in the fxmls. That said: every time you load a controller, you create a _new_ instance of it (which has its fields initialized to their default value). See the first comment for guidance, its link contains the answer to your problem :) – kleopatra Jan 23 '22 at 11:15
  • 2
    You need to create a class that models the data and share a single instance of it with all the controllers. See the [linked question](https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx) (though your model is probably much simpler). Why is `HelloController` a subclass of `PizzaController`; that makes no sense. – James_D Jan 23 '22 at 19:44
  • Thanks everyone for your input but it is sorted now all I had to do was to change the variables to static. – Antazya Singh Jatrana Jan 24 '22 at 12:55
  • 1
    that's not a solution but hacking ;) Instead, learn how to pass parameters between interested parties (see f.i. the reference provided by @Sedrick) – kleopatra Jan 24 '22 at 13:34

2 Answers2

-1

Changing the variables to static resolves the issue.

  • wrong approach - static scope is nearly always (and certainly here) the wrong tool. Instead, learn how to pass parameters between controllers (and other interested parties) – kleopatra Jan 24 '22 at 13:30
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 24 '22 at 15:15
-2

You could use a dirty trick.
Let's say I have an fxml Line object and I want to make it not visible after an Event (like a mouse click), but when I change the scenes it will return back. To achieve that I will just make a static boolean object like

private static boolean visiblity=true;

Please note that you can't make @FXML object static.

When the mouse is clicked I change the boolean object to (false).
In the initialize method of the controller I write this

line.setVisible(visibilty);

So basically, what I am saying is that you can initialize static variables that have the values you want to sustain and send them to the @FXML object.
It is a long way solution but that's what worked for me.

Lost
  • 37
  • 5
  • same comment as to the self-answer of the OP: wrong approach - static scope is nearly always (and certainly here) the wrong tool. Instead, learn how to pass parameters between controllers (and other interested parties) – kleopatra Jun 28 '22 at 12:33
  • @kleopatra Bro i'm not talking about his inheriting of Controllers. that's wrong..obviously it won't be affective in his case..i'm providing another way .. not appending to his way – Lost Jun 28 '22 at 12:50
  • careful: not your bro, actually not a bro at all ;) your answer basically is _just make a static boolean object_ (or what did I misunderstand?) - and that's exactly what your should __not__ do – kleopatra Jun 28 '22 at 12:58
  • 2
    instead of getting rude you might try to explain what you really meant, best with a [mcve]. And please take the time to write real English words instead of _u_ or similar – kleopatra Jun 28 '22 at 13:48
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 28 '22 at 16:14