英文:
Removing node does not update in GridPane
问题
我试图从GridPane中移除一个节点,但当我执行gridPane.getChildren().remove(node)时,UI似乎没有更新。当TextField为空时,会出现一个标签,当填写后,它应该显示已添加订单。但是,当空的TextField标签出现时,实际填写它们后,请填写所有字段不会消失,而已添加订单正好位于其上方。
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);
            }
        }
    }
}
英文:
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:

With filled fields:

答案1
得分: 1
每次您点击按钮时,handle 方法:
- 
创建一个名为
fill的新Label实例。 - 
检查所有字段是否已填写完整。
 
当该条件为真时,它执行 gridPane.getChildren().remove(fill);,但是 fill 刚刚在步骤1中被创建,并且还没有成为 gridPane 的子元素,所以这个指令 不会做任何操作。
当执行指令 gridPane.add(fill, 0,0); 时,您将 fill 标签(带有文本“Order added”)添加到网格窗格中,执行 handle 多次时会出现这种 叠加效果。
这不是 JavaFX 的错误;GridPane 的每个单元格的行为类似于 StackPane,因此您可以很好地 将标签叠加在一起。
我建议您:
- 
删除
gridPane.getChildren().remove(fill);这条指令。 - 
将
gridPane.add(fill, 0, 0);移到handle方法之外;您必须在组件初始化时执行这一行代码 一次。 
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"));
        }
    }
}
英文:
Each time you click on your button, the handle method:
- 
Instantiates a new
Labelinstance calledfill - 
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 thehandlemethod; 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")); } } } 
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论