java - javafx 将数据发送回前一个控制器
问题描述
我有两个不同的控制器和两个不同的 FXML 视图。第一个控制器是 CashierController,里面有一个按钮来打开新的场景和新的控制器 AddProductController。在这个收银员控制器中,购物车被初始化以根据购物车项目填充表格视图。
Second, open Addproductcontroller when click that button with new scene while prev cashiercontroller still open.inside AddProductController have the gridpane,when choose any cell inside the gridpane will add the product to cart.
问题是购物车没有更新,我不能用来刷新列表和重建表,因为 CashierController 中的方法。我想如何将数据传回仍然打开的前一个控制器,而我仍然处于当前状态(addproductController)。如何在 2 个控制器之间进行通信以接收来自新场景的返回和/或监听事件。
public class CashierController implements Initializable {
public Button btnAdd;
public JFXButton btnExit;
public TableView<Item> tableView;
public TableColumn<Item, String> colQty;
public TableColumn<Item, String> colName;
public TableColumn<Item, String> colPrice;
public JFXTextField txtBarcode;
@FXML
private Label lblAmount;
@FXML
private Label lblInfo;
Cart cart;
ProductModel productModel;
// private CashierController (){}
//
public static CashierController getInstance(){
return CashierControllerHolder.INSTANCE;
}
private static class CashierControllerHolder {
private static final CashierController INSTANCE = new CashierController();
}
@Override
public void initialize(URL location, ResourceBundle resources) {
productModel = new ProductModel();
cart = new Cart();
}
public void calculateView() {
lblSubtotal.setText(cart.getSubTotal().toString());
lblTax.setText(cart.getChargesTax().toString());
lblTotal.setText(cart.getTotal().toString());
}
public void refreshList() {
ObservableList<Item> items = FXCollections.observableArrayList(cart.getItemList());
setCellTable();
tableView.setItems(items);
}
public void addToCart(Product product) {
cart.add(product.getId(), product.getBarcode(),product.getName(), 1, product.getPrice_sell());
}
public void addProductAction(ActionEvent actionEvent) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/views/subview/addProduct.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root1));
AddProductController addProductControllerController = fxmlLoader.getController();
fxmlLoader.setController(addProductControllerController);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setCellTable(){
colQty.setCellValueFactory(new PropertyValueFactory<>("quantity"));
colName.setCellValueFactory(new PropertyValueFactory<>("name"));
colPrice.setCellValueFactory(
cellData ->{
SimpleStringProperty property = new SimpleStringProperty();
property.set(df1.format(cellData.getValue().getTotal()));
return property;
});
}
}
这是 AddProductController
public class AddProductController implements Initializable , ProductInterface {
@FXML
public Tab tabAll;
@FXML
public BorderPane borderPaneAll;
public JFXButton btnExit;
private GridPane gridPane = new GridPane();
private ProductModel productModel;
@Override
public void initialize(URL location, ResourceBundle resources) {
productModel = new ProductModel();
loadData();
Label[] label = new Label[PRODUCTLIST.size()];
Label[] labelBarcode = new Label[PRODUCTLIST.size()];
Label[] labelPrice = new Label[PRODUCTLIST.size()];
VBox vBoxes[] = new VBox[4];
int cols=2, colCnt = 0, rowCnt = 0;
for (int i=0; i<PRODUCTLIST.size(); i++) {
label[i] = new Label();
labelBarcode[i] = new Label();
labelPrice[i] = new Label();
label[i].setText(PRODUCTLIST.get(i).getName());
labelBarcode[i].setText(PRODUCTLIST.get(i).getBarcode());
labelPrice[i].setText(String.valueOf(PRODUCTLIST.get(i).getPrice_sell()));
vBoxes[i] = new VBox(5);
vBoxes[i].getChildren().addAll(label[i],labelBarcode[i], labelPrice[i]);
gridPane.add(vBoxes[i], colCnt, rowCnt);
gridPane.setHgap(20);
gridPane.setVgap(20);
colCnt++;
if (colCnt>cols) {
rowCnt++;
colCnt=0;
}
}
borderPaneAll.setCenter(gridPane);
addGridEvent();
}
private void addGridEvent() {
gridPane.getChildren().forEach(item -> {
item.setOnMouseClicked(new EventHandler<MouseEvent>() {
String name = null;
String barcode = null;
BigDecimal price = new BigDecimal(0.00);
List<String> t = new ArrayList<>();
@Override
public void handle(MouseEvent event) {
if (event.getClickCount() == 2) {
if(item instanceof VBox){
for(Node nodeIn: ((VBox) item).getChildren()){
if(nodeIn instanceof Label){
t.add(((Label)nodeIn).getText());
}
}
}
name = t.get(0);
barcode = t.get(1);
price = new BigDecimal(t.get(2));
Product product = productModel.getProductByBarcode(barcode);
//add product to cart
CashierController.getInstance().addToCart(product);
//refreshthelist
//calculatethevalue
// CashierController.getInstance().refreshList();
// CashierController.getInstance().calculateView();
}
if (event.isPrimaryButtonDown()) {
System.out.println("PrimaryKey event");
}
}
});
});
}
private void loadData(){
if (!PRODUCTLIST.isEmpty()) {
PRODUCTLIST.clear();
}
PRODUCTLIST.addAll(productModel.getProducts());
}
}
将产品添加到购物车是在网格窗格内单击。我尝试使用静态实例,但出现空异常错误。预先感谢。
解决方案
改变
AddProductController addProductControllerController = fxmlLoader.getController();
fxmlLoader.setController(addProductControllerController);
stage.show();
到
AddProductController addProductControllerController = fxmlLoader.getController();
fxmlLoader.setController(addProductControllerController);
stage.showAndWait();
“showAndWait”命令之后列出的所有代码都将等待对话框关闭后再运行。因此,基本上您可以为 AddProductController 返回的任何数据放置一个公共 getter 方法,并在 stage.showAndWait 之后在主 CashierController 中调用它
像这样的东西
AddProductController addProductControllerController = fxmlLoader.getController();
fxmlLoader.setController(addProductControllerController);
stage.showAndWait();
Product product = addProductControllerController.getScannedProduct();
推荐阅读
- python - 如果使用 func() 有多个输出,我如何获取函数输出的长度?
- deeplink - 如何通过 MS 团队中的深度链接发送消息?
- nginx - 如何在生产环境中运行的 Nginx 上安装 Geoip2 模块?
- java - 等效插座。听在 python 中,在 java 中有什么?
- mysql - java.sql.SQLIntegrityConstraintViolationException:列“question_id”不能为空
- c++ - Protobuf ShortDebugString() 崩溃
- java - 如何将咖啡因缓存设置为不过期
- linux - Bash 按关键字排序列表
- node.js - 如何在节点中导入别名?
- mysql - Hangfire在'hangfireSet中的'rank附近使用mysql不正确的语法