You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX中根据用户输入动态生成TextField数组的实现难题

JavaFX栈结构GUI程序:动态生成TextField问题

我正在用JavaFX开发一个栈结构的GUI程序,需求是先询问用户栈的元素数量,再根据输入数量在界面右侧生成对应个数的TextField,但折腾了一整天都没实现。解决TextField数组的动态生成问题后就能完成整个程序。

当前代码:

public class StackGUI extends Application {
    private Button push, pop, peek, empty, create, build;
    private TextField[] data;
    private TextField size, numberText;
    private Label sizeLabel, numberLabel;
    private int sizeOfStack;

    String sizeDialog = "0";
    
    @Override
    public void start(Stage primaryStage) {
        BorderPane border = new BorderPane();
        
        // Buttons
        push = new Button("PUSH");
        push.setPrefSize(150, 50);

        pop = new Button("POP");
        pop.setPrefSize(150, 50);

        peek = new Button("PEEK");
        peek.setPrefSize(150, 50);

        empty = new Button("EMPTY");
        empty.setPrefSize(150, 50);

        FlowPane bottom = new FlowPane();
        bottom.setHgap(10);
        bottom.setAlignment(Pos.CENTER);
        bottom.getChildren().addAll(push, pop, peek, empty);

        border.setBottom(bottom);
        
        //Center
        VBox center = new VBox(5);
        center.setAlignment(Pos.CENTER);

        size = new TextField();
        size.setMaxWidth(200);
        size.setEditable(false);

        numberLabel = new Label("Enter a number: ");
        numberText = new TextField();
        numberText.setMaxWidth(200);
        //sizeLabel = new Label("How many numbers? ");

        create = new Button("Create a stack");
        create.setPrefWidth(200);

        build = new Button("Build the stack");
        build.setPrefWidth(200);
        build.setDisable(true);

        center.getChildren().addAll(create, size, build);

        border.setCenter(center);
        
        //Stack TextFields --> right
         
        create.setOnAction(ae -> {
            TextInputDialog input = new TextInputDialog();
            input.setContentText("How many Numbers");
            input.setHeaderText("Size Of Stack");
            input.setTitle("Stack");
            input.showAndWait();

            size.setAlignment(Pos.CENTER);
            size.setText("Number Of Elements: " + input.getEditor().getText());

            sizeDialog = input.getEditor().getText();

            build.setDisable(false);
        });
        
        sizeOfStack = Integer.parseInt(sizeDialog);
        data = new TextField[sizeOfStack];
        HBox right = new HBox(5);
        build.setOnAction(ae -> {
            create.setDisable(true);
            numberText.setPromptText("Enter a number to push");
            center.getChildren().addAll(numberLabel, numberText);
            for (int i = 0; i < sizeOfStack; i++) {
                data[i] = new TextField();
                right.getChildren().add(data[i]);
            }
        });

        border.setRight(right);
        
        //Scene
        Scene scene = new Scene(border, 800, 400);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Stack");
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args); 
    }
}

程序界面截图:
StackGUI程序界面


问题分析

你的代码核心问题在于栈大小的初始化时机错误:

  • sizeOfStack = Integer.parseInt(sizeDialog); 和 data = new TextField[sizeOfStack]; 在start方法启动时就执行了,此时用户还没输入栈的大小,sizeDialog是初始值"0",导致数组长度为0,后续循环生成TextField时不会执行任何操作。
  • 即使用户后续输入了栈大小,已经初始化的sizeOfStack和data数组不会自动更新,依然是初始的0长度。

修复方案

把数组初始化和TextField生成的逻辑移到build按钮的事件处理器中,确保使用用户输入的最新栈大小,同时添加输入合法性校验(避免非数字输入报错):

修改后的代码:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.Optional;

public class StackGUI extends Application {
    private Button push, pop, peek, empty, create, build;
    private TextField[] data;
    private TextField size, numberText;
    private Label numberLabel;
    private int sizeOfStack;

    String sizeDialog = "0";
    
    @Override
    public void start(Stage primaryStage) {
        BorderPane border = new BorderPane();
        
        // 底部按钮区
        push = new Button("PUSH");
        push.setPrefSize(150, 50);

        pop = new Button("POP");
        pop.setPrefSize(150, 50);

        peek = new Button("PEEK");
        peek.setPrefSize(150, 50);

        empty = new Button("EMPTY");
        empty.setPrefSize(150, 50);

        FlowPane bottom = new FlowPane();
        bottom.setHgap(10);
        bottom.setAlignment(Pos.CENTER);
        bottom.getChildren().addAll(push, pop, peek, empty);
        border.setBottom(bottom);
        
        // 中间操作区
        VBox center = new VBox(5);
        center.setAlignment(Pos.CENTER);

        size = new TextField();
        size.setMaxWidth(200);
        size.setEditable(false);

        numberLabel = new Label("Enter a number: ");
        numberText = new TextField();
        numberText.setMaxWidth(200);

        create = new Button("Create a stack");
        create.setPrefWidth(200);

        build = new Button("Build the stack");
        build.setPrefWidth(200);
        build.setDisable(true);

        center.getChildren().addAll(create, size, build);
        border.setCenter(center);
        
        // 右侧TextField容器
        HBox right = new HBox(5);
        right.setAlignment(Pos.CENTER);
        border.setRight(right);
         
        // 创建栈按钮事件
        create.setOnAction(ae -> {
            TextInputDialog input = new TextInputDialog();
            input.setContentText("How many Numbers");
            input.setHeaderText("Size Of Stack");
            input.setTitle("Stack");
            Optional<String> result = input.showAndWait();
            
            // 校验输入合法性
            if (result.isPresent()) {
                try {
                    int inputSize = Integer.parseInt(result.get());
                    if (inputSize <= 0) {
                        Alert alert = new Alert(Alert.AlertType.ERROR);
                        alert.setTitle("Input Error");
                        alert.setContentText("Please enter a positive integer");
                        alert.showAndWait();
                        return;
                    }
                    sizeDialog = result.get();
                    size.setAlignment(Pos.CENTER);
                    size.setText("Number Of Elements: " + sizeDialog);
                    build.setDisable(false);
                } catch (NumberFormatException e) {
                    Alert alert = new Alert(Alert.AlertType.ERROR);
                    alert.setTitle("Input Error");
                    alert.setContentText("Please enter a valid integer");
                    alert.showAndWait();
                }
            }
        });
        
        // 构建栈按钮事件
        build.setOnAction(ae -> {
            create.setDisable(true);
            numberText.setPromptText("Enter a number to push");
            center.getChildren().addAll(numberLabel, numberText);
            
            // 使用用户输入的最新值初始化数组
            sizeOfStack = Integer.parseInt(sizeDialog);
            data = new TextField[sizeOfStack];
            
            // 清空旧的TextField,避免重复生成
            right.getChildren().clear();
            
            // 生成对应数量的TextField
            for (int i = 0; i < sizeOfStack; i++) {
                data[i] = new TextField();
                data[i].setPrefWidth(80); // 设置固定宽度优化显示
                right.getChildren().add(data[i]);
            }
        });
        
        // 场景设置
        Scene scene = new Scene(border, 800, 400);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Stack");
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args); 
    }
}

关键修改点

  1. 将右侧HBox容器的初始化提前,确保它在界面启动时就被添加到布局中。
  2. 把sizeOfStack和data数组的初始化逻辑移到build按钮的事件处理器内,保证使用用户输入的最新栈大小。
  3. 添加输入合法性校验,拦截非数字、负数输入,避免程序崩溃。
  4. 添加right.getChildren().clear(),防止重复点击build按钮生成重复的TextField。
  5. 给每个TextField设置固定宽度,优化界面显示效果。

内容的提问来源于stack exchange,提问作者javaDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:45:35