Jarrell Tan
Jarrell Tan

Reputation: 13

Removing node does not update in GridPane

I'm trying to remove a node from the GridPane but when I do gridPane.getChildren().remove(node), it doesn't seem to be updated in the UI. I have a label that comes up when there's an empty TextField, and when they are filled it should say Order added. But when the empty TextField label comes up and when I actually fill them up, Please fill all fields doesn't go away and Order added is just right on top of it.

import java.awt.*;
import java.util.ArrayList;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.event.ActionEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import javafx.scene.text.Text;
import javafx.geometry.Pos;
import javafx.scene.control.TextField;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.paint.Color;
import javax.swing.*;

public class InputPane extends HBox
{
    ArrayList < Order > orderList;

    private HandlePane handlePane;

    TextField textField1 = new TextField();
    TextField textField2 = new TextField();
    TextField textField3 = new TextField();

    Label prodName, quantity, price, fill = new Label();

    Button place_an_order;

    GridPane gridPane;
    TextArea textArea;

    public InputPane(ArrayList < Order > list, HandlePane pane)
    {
        this.orderList = list;
        this.handlePane = pane;

        prodName = new Label("Prod. Name");
        quantity = new Label ("Quantity");
        price = new Label ("Price($)");
        prodName.setMinWidth(Region.USE_PREF_SIZE);

        place_an_order = new Button("Place an Order");

        gridPane = new GridPane();
        gridPane.setPadding(new Insets(10,20,10,20));
        gridPane.setVgap(10);
        gridPane.setHgap(10);

        gridPane.add(prodName, 0, 1);
        gridPane.add(textField1, 1,1);
        gridPane.add(quantity, 0,2);
        gridPane.add(textField2, 1,2);
        gridPane.add(price, 0,3);
        gridPane.add(textField3, 1,3);
        gridPane.add(place_an_order, 1,4);

        textArea = new TextArea();
        textArea.setText("No order");
        textArea.setPrefSize(320,120);

        this.getChildren().addAll(gridPane, textArea);

        ButtonHandler handler = new ButtonHandler();
        place_an_order.setOnAction(handler);
    }

    private class ButtonHandler implements EventHandler < ActionEvent >{
        public void handle(ActionEvent e){
            String productStr = textField1.getText().trim();
            String quantityStr = textField2.getText().trim();
            String priceStr = textField3.getText().trim();

            fill.setTextFill(Color.web("FF0000"));
            fill.setMinWidth(Region.USE_PREF_SIZE);

            if (productStr.isEmpty() || quantityStr.isEmpty() || priceStr.isEmpty())
            {
                fill.setText("Please fill all the fields");
                fill.setTextFill(Color.web("FF0000"));
                fill.setMinWidth(Region.USE_PREF_SIZE);
            }else{
                fill.setText("Order added");
                fill.setTextFill(Color.web("#000000"));
                gridPane.add(fill, 0,0);
            }
        }
    }
}

With empty fields:

This is what happens when at least one text field is empty

With filled fields:

And that's what happens when I actually fill the text fields

Upvotes: 0

Views: 393

Answers (1)

0009laH
0009laH

Reputation: 2000

Each time you click on your button, the handle method:

  1. Instantiates a new Label instance called fill

  2. Checks whether all fields are completed.

When that condition is true, it executes gridPane.getChildren().remove(fill);, but fill has just been instantiated in step 1 and is not a children of gridPane yet, so the instruction doesn't do anything.

When the instruction gridPane.add(fill, 0,0); is executed, you add the fill label (with text "Order added") inside the grid pane and you get this overlay effect when executing handle several times.

This is not a JavaFX bug; each cell of a GridPane behaves line a StackPane, so you can perfectly add labels above each other.


I would recommend you to:

  • Remove the gridPane.getChildren().remove(fill); instruction

  • Move gridPane.add(fill, 0, 0); outside the handle method; you have to execute this line once (at the initialization of the component).

    private class ButtonHandler implements EventHandler <ActionEvent> {
        Label fill;
    
        public ButtonHandler() {
            fill = new Label();
            fill.setTextFill(Color.web("FF0000"));
            fill.setMinWidth(Region.USE_PREF_SIZE);
    
            gridPane.add(fill, 0, 0);
        }
    
        public void handle(ActionEvent e) {
            String productStr = textField1.getText().trim();
            String quantityStr = textField2.getText().trim();
            String priceStr = textField3.getText().trim();
    
            if (productStr.isEmpty() || quantityStr.isEmpty() || priceStr.isEmpty()) {
                fill.setText("Please fill all the fields");
                fill.setTextFill(Color.web("FF0000"));
            } else {
                fill.setText("Order added");
                fill.setTextFill(Color.web("#000000"));
            }
        }
    }
    

Upvotes: 1

Related Questions