Search code examples
javajavafxjavafx-8default-constructorborderpane

How can a class like BorderPane display the change when it is later being coded and not when initialised?


I was working on JavaFX, and I realised something which kept me thinking. So, there's a scene in my constructor which adds the variable root of the type BorderPane. In the main class, this class' constructor is called first, thereby initialising the BorderPane in the Scene. However, the BorderPane is being modified and edited in a method called build. I am confused how the BorderPane is still being able to display its updated version from the build() since in the constructor it has already been commanded to display.

Here's my code:

 public class SnacksOrDrinks
    {
        private BorderPane root;
        private Stage primaryStage;
        private Scene scene;
        private Cart crt;

        public SnacksOrDrinks(Stage primaryStage, Cart crt)
        {
        // BorderPane is being initialised and is being put inside the scene: 
                BorderPane root1 = new BorderPane();        
                this.scene = new Scene(root1, 800, 475);
                this.crt = crt;

            ImageView imgview = new ImageView("./application/MountainPainting.jpg");
            imgview.fitWidthProperty().bind(primaryStage.widthProperty());
            imgview.fitHeightProperty().bind(primaryStage.heightProperty());

            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            this.primaryStage = primaryStage;
            this.root = root1;
            root.setStyle("-fx-background-color: blue");


            root.getChildren().add(imgview);
        }

        public void build(Dispenser dis)
        {
            // ItemsPaneProp extends GridPane and stores the common properties shared in other classes.
            ItemsPaneProp pane = new ItemsPaneProp();       

            // Header Created: 
            CommHeaderProp header = new CommHeaderProp("Lopes Vending Machine");


    // However, BorderPane is being modified here, and the constructor has already been called. 
            BorderPane.setAlignment(header, Pos.CENTER);
            root.setTop(header);

            // Create a Line: 
            Line line = new Line(100, 10, 300, 10);
            line.setFill(Color.GOLDENROD);
            line.setStrokeWidth(2);
            line.setSmooth(true);
            pane.add(line, 0, 0);

            // Create all the Scene's Components and setup the Event Handlers
            ImageView img = new ImageView("./application/softdrink.jpg");
            img.setFitWidth(75);
            img.setFitHeight(75);
            Button btn1 = new Button("Select to get Drinks", img);
            btn1.setStyle("-fx-background-color: white");
            btn1.setFont(Font.font("Times New Roman", FontWeight.BOLD, FontPosture.REGULAR, 12));
            btn1.setContentDisplay(ContentDisplay.TOP);
            pane.add(btn1, 0, 1);

            ImageView img1 = new ImageView("./application/potato-chips.png");
            img1.setFitWidth(75);
            img1.setFitHeight(75);
            Button btn2 = new Button("Select to get Snacks", img1);
            btn2.setStyle("-fx-background-color: white");
            btn2.setFont(Font.font("Times New Roman", FontWeight.BOLD, FontPosture.REGULAR, 12));
            btn2.setContentDisplay(ContentDisplay.TOP);`enter code here`
            pane.add(btn2, 1, 1);

            root.setCenter(pane); // The BorderPane is being modified here too, but the constructor isn't updating the scene. Then, how does it still work?

            btn1.setOnMouseClicked(new EventHandler<MouseEvent>()
            {
                @Override
                public void handle(MouseEvent e)
                {
                    // Create, build, and show Scene 2
                    DrinksList scene = new DrinksList(primaryStage, crt);
                    scene.build(dis);
                    scene.show();
                }
            });

            btn2.setOnMouseClicked(new EventHandler<MouseEvent>()
            {
                @Override
                public void handle(MouseEvent e)
                {
                    // Create, build, and show Scene 2
                    SnacksList scene = new SnacksList(primaryStage, crt);
                    scene.build(dis);
                    scene.show();
                }
            });

        }

        public void show()
        {// setting scene:
            primaryStage.setScene(scene);
        }
    }

Solution

  • Take a look at https://docs.oracle.com/javase/8/javafx/scene-graph-tutorial/scenegraph.htm#JFXSG107

    The JavaFX scene graph is a retained mode API, meaning that it maintains an internal model of all graphical objects in your application. At any given time, it knows what objects to display, what areas of the screen need repainting, and how to render it all in the most efficient manner.

    Your borderPane - part of SceneGraph, so JavaFX knows, when you change anything in your borderPane, and automatically invoking redraw method for it.