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

Java井字棋游戏:实现TextArea等待ENTER输入后返回位置

解决JavaFX井字棋中TextArea等待用户输入回车的问题

你的问题核心有两个:一是JavaFX UI线程被阻塞了,start方法里的while(true)会卡死UI线程,导致用户根本没法在ta1里输入内容,player_input()自然读不到值;二是你没有监听回车事件,没法触发输入完成的逻辑,直接读取ta1文本肯定是空的,进而抛出NumberFormatException导致崩溃。

下面是具体的解决方案和重构后的代码:

关键修复思路

  1. 移除阻塞UI的死循环:JavaFX的所有UI操作都依赖主线程(UI线程),死循环会占用这个线程,导致用户输入、界面渲染完全无法响应。我们改成事件驱动的方式,等用户输入完成后再执行游戏逻辑。
  2. 添加回车事件监听:给ta1绑定回车按键监听,当用户输入位置并按下回车时,再读取输入内容并处理游戏流程。
  3. 用状态变量管理游戏进度:通过变量记录当前玩家,输入完成后自动切换玩家,推进游戏。

重构后的完整代码

import extendsFX.BaseConsole;
import static extendsFX.BaseApps.nL;
import javafx.scene.input.KeyCode;
import javafx.stage.Stage;

public class tictactoe extends BaseConsole {
    // 游戏状态:当前回合玩家,初始为Player1(X)
    private char currentPlayer = 'X';
    private char[] board = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};

    void display_board(char[] board) {
        ta2.clear(); // 先清空再重新绘制棋盘
        ta2.appendText(" | | " + nL);
        ta2.appendText(" " + board[7] + " | " + board[8] + " | " + board[9] + " " + nL);
        ta2.appendText(" | | " + nL);
        ta2.appendText("-----------" + nL);
        ta2.appendText(" | | " + nL);
        ta2.appendText(" " + board[4] + " | " + board[5] + " | " + board[6] + " " + nL);
        ta2.appendText(" | | " + nL);
        ta2.appendText("-----------" + nL);
        ta2.appendText(" | | " + nL);
        ta2.appendText(" " + board[1] + " | " + board[2] + " | " + board[3] + " " + nL);
        ta2.appendText(" | | " + nL);
    }

    boolean is_over(char[] board) {
        // 简化胜负判断逻辑,功能和原代码一致
        return (board[1] == board[2] && board[2] == board[3] && board[1] != ' ')
                || (board[4] == board[5] && board[5] == board[6] && board[4] != ' ')
                || (board[7] == board[8] && board[8] == board[9] && board[7] != ' ')
                || (board[1] == board[4] && board[4] == board[7] && board[1] != ' ')
                || (board[2] == board[5] && board[5] == board[8] && board[2] != ' ')
                || (board[3] == board[6] && board[6] == board[9] && board[3] != ' ')
                || (board[1] == board[5] && board[5] == board[9] && board[1] != ' ')
                || (board[3] == board[5] && board[5] == board[7] && board[3] != ' ');
    }

    // 重构:只负责放置标记,返回是否放置成功
    boolean place_marker(char[] board, char marker, int position) {
        if (position < 1 || position > 9) {
            ta2.appendText("无效位置!请输入1-9之间的数字。" + nL);
            return false;
        }
        if (board[position] == ' ') {
            board[position] = marker;
            return true;
        } else {
            ta2.appendText("该位置已被占用!请选择其他位置。" + nL);
            return false;
        }
    }

    boolean is_full(char[] board) {
        for (int n = 1; n < 10; n++) {
            if (board[n] == ' ') return false;
        }
        return true;
    }

    boolean check_for_draw(char[] board) {
        if (!is_over(board) && is_full(board)) {
            ta2.appendText("平局!" + nL);
            return true;
        }
        return false;
    }

    // 处理玩家输入后的游戏逻辑
    private void handlePlayerInput(int position) {
        // 尝试放置标记
        if (place_marker(board, currentPlayer, position)) {
            display_board(board);
            // 检查胜负
            if (is_over(board)) {
                ta2.appendText("玩家" + (currentPlayer == 'X' ? 1 : 2) + "获胜!" + nL);
                ta1.setDisable(true); // 游戏结束,禁用输入框
                return;
            }
            // 检查平局
            if (check_for_draw(board)) {
                ta1.setDisable(true);
                return;
            }
            // 切换玩家
            currentPlayer = currentPlayer == 'X' ? 'O' : 'X';
            ta2.appendText("玩家" + (currentPlayer == 'X' ? 1 : 2) + "的回合:" + nL);
        }
        ta1.clear(); // 清空输入框,方便下一次输入
    }

    @Override
    public void createControls() {
        super.createControls();
        // 给ta1添加回车按键监听
        ta1.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) {
                try {
                    int location = Integer.parseInt(ta1.getText().trim());
                    handlePlayerInput(location);
                } catch (NumberFormatException e) {
                    ta2.appendText("请输入有效的数字(1-9)!" + nL);
                    ta1.clear();
                }
            }
        });
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("TicTacToe");
        super.start(stage);
        // 初始化游戏界面
        display_board(board);
        ta2.appendText("玩家1的回合:" + nL);
    }

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

额外说明

  • 确保你的BaseConsole类正确初始化了ta1和ta2这两个TextArea组件,否则会出现NullPointerException。
  • 棋盘的位置对应关系:1=左下角,9=右上角,这个可以在界面上提示用户,避免输入困惑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:16:22