【发布时间】:2022-01-23 04:26:26
【问题描述】:
我一直在尝试实现的是一个 JavaFX 应用程序,它计算通过各种类别选择的项目的成本,在这种情况下只有两个:比萨饼和汉堡。
当我单击带有文本“pizzas”的按钮时,pizzas.fxml 文件被加载,我选择一个项目,因此变量 Pizzatotal 增加,然后我回到主页。直到这一步,变量 Pizzatotal 的值保持与它更改为的增量值相同。但是一旦我从主页点击按钮“汉堡”,变量 Pizzatotal 的值就会重置为 0。
我希望变量 Pizzatotal 的值在应用程序中的场景之间的整个导航过程中保持不变。
我一共构建了 3 个 fxml 文件。 一个用于主页,其中包含两个按钮,分别用于导航到第二页和第三页。
这是主页的 fxml 代码:
"'
<?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>
第二个 FXML 文件包含一个网格窗格,其中包含用于执行不同方法的按钮。坦率地说,这个屏幕上的每个按钮都会将所选披萨的成本添加到变量中:total。
第二个FXML文件的代码如下:
"'
<?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>
'"
第三个 FXML 文件也与此完全相同,因此我没有将代码包含在其中以缩短它。
我已经构建了 3 个差异控制器类来控制主页面、比萨饼页面和汉堡页面。
主页面的控制器类如下:
"'
公共类 HelloController 扩展 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();
}
}'"
方法'switchtopizzapage'打开披萨页面,这是第二个FXML场景,'switchtoburger'打开第三个FXML场景。
主页面如下所示:
pizzas.fxml 文件的控制器类如下:
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();
}
}
Burgers.fxml 的控制器类如下:
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();
}
}
【问题讨论】:
-
处理在
FXML文件中创建的变量时,Controller中的Button gottomainfromburger = new Button()是禁止的。应该是@FXML Button gottomainfromburger;除此之外,您应该查看MCV。如果您使用@James_D 答案中的想法,那应该可以解决您在更改场景时遇到的问题。 -
创建一个minimal reproducible example 并编辑您的问题以包含它。您发布的代码中有很多错误,但还不够完整,无法知道导致您观察到的问题的原因。这不是真正可以回答的。
-
请重新阅读@James_D 的评论,彻底研究引用的帮助页面并采取相应的行动:您的代码不可重现 - 缺少应用程序 - 并且仅接近(虽然不远)到最小 -在 fxmls 中包含不相关的绒毛。也就是说:每次加载控制器时,都会创建它的 new 实例(其字段已初始化为其默认值)。请参阅第一条评论以获取指导,其链接包含您问题的答案:)
-
您需要创建一个类来对数据进行建模并与所有控制器共享它的单个实例。请参阅linked question(尽管您的模型可能要简单得多)。为什么
HelloController是PizzaController的子类;这没有任何意义。 -
这不是解决方案,而是 hacking ;) 相反,学习如何在相关方之间传递参数(参见 f.i. @Sedrick 提供的参考)
标签: java intellij-idea javafx