问题
I have two different controller with two different FXML view. First controller is CashierController,there is button inside to open new scene and with new controller AddProductController. In this cashiercontroller the was cart to initialize to populate the tableview based on cart item.
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.
The problem was the the cart not update and i cant use to refresh the list and rebuild the table because method in CashierController. How i want to pass back the data to previous controller that still open, while i still at current(addproductController).How to communicate the between 2 controller to receive back and or listen event from new to prev scene.
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;
});
}
}
this is 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());
}
}
The add product to cart was in click inside gridpane. Im try use static instance but error in null exception. Thank in advance.
回答1:
Change
AddProductController addProductControllerController = fxmlLoader.getController();
fxmlLoader.setController(addProductControllerController);
stage.show();
to
AddProductController addProductControllerController = fxmlLoader.getController();
fxmlLoader.setController(addProductControllerController);
stage.showAndWait();
All code listed after the "showAndWait" command will wait for the dialog to close before running. So essentially you can place a public getter method for whatever data your AddProductController is returning and call that in the main CashierController after the stage.showAndWait
Something like this
AddProductController addProductControllerController = fxmlLoader.getController();
fxmlLoader.setController(addProductControllerController);
stage.showAndWait();
Product product = addProductControllerController.getScannedProduct();
来源:https://stackoverflow.com/questions/50727894/javafx-send-back-data-to-previous-controller