移除节点后在GridPane中未更新。

huangapple go评论92阅读模式
英文:

Removing node does not update in GridPane

问题

我试图从GridPane中移除一个节点,但当我执行gridPane.getChildren().remove(node)时,UI似乎没有更新。当TextField为空时,会出现一个标签,当填写后,它应该显示已添加订单。但是,当空的TextField标签出现时,实际填写它们后,请填写所有字段不会消失,而已添加订单正好位于其上方。

  1. import java.awt.*;
  2. import java.util.ArrayList;
  3. import javafx.event.EventHandler;
  4. import javafx.geometry.HPos;
  5. import javafx.geometry.Insets;
  6. import javafx.scene.input.MouseEvent;
  7. import javafx.scene.layout.HBox;
  8. import javafx.event.ActionEvent;
  9. import javafx.scene.layout.GridPane;
  10. import javafx.scene.layout.Region;
  11. import javafx.scene.text.Text;
  12. import javafx.geometry.Pos;
  13. import javafx.scene.control.TextField;
  14. import javafx.scene.control.Label;
  15. import javafx.scene.control.Button;
  16. import javafx.scene.control.TextArea;
  17. import javafx.scene.paint.Color;
  18. import javax.swing.*;
  19. public class InputPane extends HBox
  20. {
  21. ArrayList<Order> orderList;
  22. private HandlePane handlePane;
  23. TextField textField1 = new TextField();
  24. TextField textField2 = new TextField();
  25. TextField textField3 = new TextField();
  26. Label prodName, quantity, price, fill = new Label();
  27. Button place_an_order;
  28. GridPane gridPane;
  29. TextArea textArea;
  30. public InputPane(ArrayList<Order> list, HandlePane pane)
  31. {
  32. this.orderList = list;
  33. this.handlePane = pane;
  34. prodName = new Label("Prod. Name");
  35. quantity = new Label ("Quantity");
  36. price = new Label ("Price($)");
  37. prodName.setMinWidth(Region.USE_PREF_SIZE);
  38. place_an_order = new Button("Place an Order");
  39. gridPane = new GridPane();
  40. gridPane.setPadding(new Insets(10,20,10,20));
  41. gridPane.setVgap(10);
  42. gridPane.setHgap(10);
  43. gridPane.add(prodName, 0, 1);
  44. gridPane.add(textField1, 1,1);
  45. gridPane.add(quantity, 0,2);
  46. gridPane.add(textField2, 1,2);
  47. gridPane.add(price, 0,3);
  48. gridPane.add(textField3, 1,3);
  49. gridPane.add(place_an_order, 1,4);
  50. textArea = new TextArea();
  51. textArea.setText("No order");
  52. textArea.setPrefSize(320,120);
  53. this.getChildren().addAll(gridPane, textArea);
  54. ButtonHandler handler = new ButtonHandler();
  55. place_an_order.setOnAction(handler);
  56. }
  57. private class ButtonHandler implements EventHandler<ActionEvent>{
  58. public void handle(ActionEvent e){
  59. String productStr = textField1.getText().trim();
  60. String quantityStr = textField2.getText().trim();
  61. String priceStr = textField3.getText().trim();
  62. fill.setTextFill(Color.web("FF0000"));
  63. fill.setMinWidth(Region.USE_PREF_SIZE);
  64. if (productStr.isEmpty() || quantityStr.isEmpty() || priceStr.isEmpty())
  65. {
  66. fill.setText("Please fill all the fields");
  67. fill.setTextFill(Color.web("FF0000"));
  68. fill.setMinWidth(Region.USE_PREF_SIZE);
  69. }else{
  70. fill.setText("Order added");
  71. fill.setTextFill(Color.web("#000000"));
  72. gridPane.add(fill, 0,0);
  73. }
  74. }
  75. }
  76. }
英文:

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.

  1. import java.awt.*;
  2. import java.util.ArrayList;
  3. import javafx.event.EventHandler;
  4. import javafx.geometry.HPos;
  5. import javafx.geometry.Insets;
  6. import javafx.scene.input.MouseEvent;
  7. import javafx.scene.layout.HBox;
  8. import javafx.event.ActionEvent;
  9. import javafx.scene.layout.GridPane;
  10. import javafx.scene.layout.Region;
  11. import javafx.scene.text.Text;
  12. import javafx.geometry.Pos;
  13. import javafx.scene.control.TextField;
  14. import javafx.scene.control.Label;
  15. import javafx.scene.control.Button;
  16. import javafx.scene.control.TextArea;
  17. import javafx.scene.paint.Color;
  18. import javax.swing.*;
  19. public class InputPane extends HBox
  20. {
  21. ArrayList &lt; Order &gt; orderList;
  22. private HandlePane handlePane;
  23. TextField textField1 = new TextField();
  24. TextField textField2 = new TextField();
  25. TextField textField3 = new TextField();
  26. Label prodName, quantity, price, fill = new Label();
  27. Button place_an_order;
  28. GridPane gridPane;
  29. TextArea textArea;
  30. public InputPane(ArrayList &lt; Order &gt; list, HandlePane pane)
  31. {
  32. this.orderList = list;
  33. this.handlePane = pane;
  34. prodName = new Label(&quot;Prod. Name&quot;);
  35. quantity = new Label (&quot;Quantity&quot;);
  36. price = new Label (&quot;Price($)&quot;);
  37. prodName.setMinWidth(Region.USE_PREF_SIZE);
  38. place_an_order = new Button(&quot;Place an Order&quot;);
  39. gridPane = new GridPane();
  40. gridPane.setPadding(new Insets(10,20,10,20));
  41. gridPane.setVgap(10);
  42. gridPane.setHgap(10);
  43. gridPane.add(prodName, 0, 1);
  44. gridPane.add(textField1, 1,1);
  45. gridPane.add(quantity, 0,2);
  46. gridPane.add(textField2, 1,2);
  47. gridPane.add(price, 0,3);
  48. gridPane.add(textField3, 1,3);
  49. gridPane.add(place_an_order, 1,4);
  50. textArea = new TextArea();
  51. textArea.setText(&quot;No order&quot;);
  52. textArea.setPrefSize(320,120);
  53. this.getChildren().addAll(gridPane, textArea);
  54. ButtonHandler handler = new ButtonHandler();
  55. place_an_order.setOnAction(handler);
  56. }
  57. private class ButtonHandler implements EventHandler &lt; ActionEvent &gt;{
  58. public void handle(ActionEvent e){
  59. String productStr = textField1.getText().trim();
  60. String quantityStr = textField2.getText().trim();
  61. String priceStr = textField3.getText().trim();
  62. fill.setTextFill(Color.web(&quot;FF0000&quot;));
  63. fill.setMinWidth(Region.USE_PREF_SIZE);
  64. if (productStr.isEmpty() || quantityStr.isEmpty() || priceStr.isEmpty())
  65. {
  66. fill.setText(&quot;Please fill all the fields&quot;);
  67. fill.setTextFill(Color.web(&quot;FF0000&quot;));
  68. fill.setMinWidth(Region.USE_PREF_SIZE);
  69. }else{
  70. fill.setText(&quot;Order added&quot;);
  71. fill.setTextFill(Color.web(&quot;#000000&quot;));
  72. gridPane.add(fill, 0,0);
  73. }
  74. }
  75. }
  76. }

With empty fields:

移除节点后在GridPane中未更新。

With filled fields:

移除节点后在GridPane中未更新。

答案1

得分: 1

每次您点击按钮时,handle 方法:

  1. 创建一个名为 fill 的新 Label 实例。

  2. 检查所有字段是否已填写完整。

当该条件为真时,它执行 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 方法之外;您必须在组件初始化时执行这一行代码 一次

  1. private class ButtonHandler implements EventHandler<ActionEvent> {
  2. Label fill;
  3. public ButtonHandler() {
  4. fill = new Label();
  5. fill.setTextFill(Color.web("FF0000"));
  6. fill.setMinWidth(Region.USE_PREF_SIZE);
  7. gridPane.add(fill, 0, 0);
  8. }
  9. public void handle(ActionEvent e) {
  10. String productStr = textField1.getText().trim();
  11. String quantityStr = textField2.getText().trim();
  12. String priceStr = textField3.getText().trim();
  13. if (productStr.isEmpty() || quantityStr.isEmpty() || priceStr.isEmpty()) {
  14. fill.setText("Please fill all the fields");
  15. fill.setTextFill(Color.web("FF0000"));
  16. } else {
  17. fill.setText("Order added");
  18. fill.setTextFill(Color.web("#000000"));
  19. }
  20. }
  21. }
英文:

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).

    1. private class ButtonHandler implements EventHandler &lt;ActionEvent&gt; {
    2. Label fill;
    3. public ButtonHandler() {
    4. fill = new Label();
    5. fill.setTextFill(Color.web(&quot;FF0000&quot;));
    6. fill.setMinWidth(Region.USE_PREF_SIZE);
    7. gridPane.add(fill, 0, 0);
    8. }
    9. public void handle(ActionEvent e) {
    10. String productStr = textField1.getText().trim();
    11. String quantityStr = textField2.getText().trim();
    12. String priceStr = textField3.getText().trim();
    13. if (productStr.isEmpty() || quantityStr.isEmpty() || priceStr.isEmpty()) {
    14. fill.setText(&quot;Please fill all the fields&quot;);
    15. fill.setTextFill(Color.web(&quot;FF0000&quot;));
    16. } else {
    17. fill.setText(&quot;Order added&quot;);
    18. fill.setTextFill(Color.web(&quot;#000000&quot;));
    19. }
    20. }
    21. }

huangapple
  • 本文由 发表于 2020年10月1日 12:17:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/64148994.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定