我有两个不同的控制器,有两个不同的FXML视图。 第一个控制器是CashierController,里面有按钮打开新场景和新控制器AddProductController。在这个收银员控制器中,购物车被初始化以根据购物车项目填充tableview。
第二,打开Addproductcontroller时,点击那个带有新场景的按钮,而prev cashiercontroller仍然打开。内部AddProductController有gridpane,当选择gridpane里面的任何单元格时,将产品添加到购物车。
问题是购物车没有更新,我无法刷新列表并重建表,因为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;
});
}
}
这是AddProducController
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());
}
}
添加到购物车的产品是在网格窗格内点击。我尝试使用静态实例但在null异常中出错。提前谢谢。
答案 0 :(得分:0)
更改
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();