0

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.

azra abdullah
  • 139
  • 1
  • 5
  • 12
  • I need to point out that there is no reason to get the controller out from `FXMLLoader` and then setting that back to the `FXMLLoader`. – Jai Jun 07 '18 at 01:19
  • understood,actually first im trying to send data to next stage it working. but to return i cant solve to return back the data from current to prev. Then i forgot to remove,Thanks to inform. – azra abdullah Jun 07 '18 at 01:42

1 Answers1

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();
Philip Vaughn
  • 606
  • 6
  • 20
  • thanks for answers, just asking the data only return after close the new stage,there is possibility to async ,for example when i click the gridpane, then auto update the method in prev stage without close current stage. – azra abdullah Jun 07 '18 at 01:31
  • Wow, I didn't even know you asked this in Jun '18 lol. Yes you can do this. Just put whatever it is you want it to do in a task and call the task when you click the gridpane. You can continue working and the task will be doing it's thing. Just look up Javafx Task. Here's an example https://www.developer.com/java/data/multithreading-in-javafx.html – Philip Vaughn Jan 29 '19 at 20:06
  • already forgot what im asking, anyway javafx project already done.maybe this question will benefit others – azra abdullah Jan 29 '19 at 21:02