JavaFX影院系统:如何将弹窗TextField的Double值传递至主界面并累加
解决JavaFX影院系统中饮料弹窗总价传递至主界面的问题
我来帮你搞定这个问题!你当前的代码没办法把饮料总价正确传递到主界面并更新显示,核心问题有两个:
问题分析
- 错误的控制器实例引用:你在
DrinksController里新建了一个FilmsController实例private FilmsController fc = new FilmsController();,但这个实例和主界面正在运行的FilmsController完全是两个对象,就算你修改了静态的completetotal,主界面的UI也不会自动刷新。 - 静态变量的不合理使用:直接用静态变量
completetotal传递数据会让代码耦合度极高,而且JavaFX的UI控件不会自动监听静态变量的变化来更新显示。
解决方案:使用回调函数传递数据(推荐)
我们可以用Java的Consumer回调接口,让饮料弹窗把计算好的总价主动传递给主界面,由主界面负责累加和更新UI,这样既解耦又能保证UI正确刷新。
第一步:修改DrinksController代码
去掉静态变量依赖,添加回调接口来传递总价:
import javafx.event.ActionEvent; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.stage.Stage; import java.util.function.Consumer; public class DrinksController { public TextField watertf; public TextField coketf; public Button totalbut; public TextField totaltf; public Button finishdrinks2; // 回调接口,用于将饮料总价传递回主界面 private Consumer<Double> onDrinksTotalCalculated; // 设置回调的方法,让主界面注册处理逻辑 public void setOnDrinksTotalCalculated(Consumer<Double> callback) { this.onDrinksTotalCalculated = callback; } public void addrinks(ActionEvent actionEvent) { try { int water = Integer.parseInt(watertf.getText()); int coke = Integer.parseInt(coketf.getText()); double result = water * 1.75 + coke * 1.25; totaltf.setText(String.valueOf(result)); } catch (NumberFormatException e) { totaltf.setText("Not a Number"); } } public void finishdrinksclose2(ActionEvent actionEvent) { try { int water = Integer.parseInt(watertf.getText()); int coke = Integer.parseInt(coketf.getText()); double drinksTotal = water * 1.75 + coke * 1.25; totaltf.setText(String.valueOf(drinksTotal)); // 如果主界面注册了回调,就把饮料总价传递回去 if (onDrinksTotalCalculated != null) { onDrinksTotalCalculated.accept(drinksTotal); } Stage stage = (Stage) finishdrinks2.getScene().getWindow(); stage.close(); } catch (NumberFormatException e) { totaltf.setText("Not a Number"); } } }
第二步:修改主界面FilmsController代码
在打开饮料弹窗时注册回调,处理总价累加和UI更新:
import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.event.ActionEvent; import java.io.IOException; public class FilmsController { public TextField adulttf; public TextField childtf; public TextField filmpricetf; public TextField totalpricetf; // 把completetotal改成非静态变量,避免多实例干扰 private double completetotal = 0.0; // 假设这是你打开饮料弹窗的方法,需要确保用FXMLLoader获取控制器实例 public void openDrinksPopup() { try { FXMLLoader loader = new FXMLLoader(getClass().getResource("drinks.fxml")); Parent root = loader.load(); DrinksController drinksController = loader.getController(); // 注册回调:接收饮料总价,累加并更新主界面的总价显示 drinksController.setOnDrinksTotalCalculated(drinksTotal -> { completetotal += drinksTotal; // 更新主界面的总价TextField totalpricetf.setText(String.valueOf(completetotal)); }); Stage stage = new Stage(); stage.setScene(new Scene(root)); stage.show(); } catch (IOException e) { e.printStackTrace(); } } public void comptotal(ActionEvent actionEvent) { try { int adult = Integer.parseInt(adulttf.getText()); int child = Integer.parseInt(childtf.getText()); double filmprice = Double.parseDouble(filmpricetf.getText()); double result = adult * filmprice + child * filmprice; completetotal += result; // 这里改成显示累计总价,而不是单场次价格 totalpricetf.setText(String.valueOf(completetotal)); } catch (NumberFormatException e) { totalpricetf.setText("Not a Number"); } } }
额外注意事项
- 确保你打开饮料弹窗时是通过
FXMLLoader加载的fxml文件,这样才能获取到正确的DrinksController实例,而不是自己new一个。 - 把
completetotal改成非静态变量,这样多个主界面实例之间不会互相影响。 - 使用
Integer.parseInt和Double.parseDouble替代new Integer(),代码更简洁高效。
内容的提问来源于stack exchange,提问作者user11185206
相关产品推荐
相关产品推荐

