Java井字棋游戏:实现TextArea等待ENTER输入后返回位置
解决JavaFX井字棋中TextArea等待用户输入回车的问题
你的问题核心有两个:一是JavaFX UI线程被阻塞了,start方法里的while(true)会卡死UI线程,导致用户根本没法在ta1里输入内容,player_input()自然读不到值;二是你没有监听回车事件,没法触发输入完成的逻辑,直接读取ta1文本肯定是空的,进而抛出NumberFormatException导致崩溃。
下面是具体的解决方案和重构后的代码:
关键修复思路
- 移除阻塞UI的死循环:JavaFX的所有UI操作都依赖主线程(UI线程),死循环会占用这个线程,导致用户输入、界面渲染完全无法响应。我们改成事件驱动的方式,等用户输入完成后再执行游戏逻辑。
- 添加回车事件监听:给
ta1绑定回车按键监听,当用户输入位置并按下回车时,再读取输入内容并处理游戏流程。 - 用状态变量管理游戏进度:通过变量记录当前玩家,输入完成后自动切换玩家,推进游戏。
重构后的完整代码
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
相关产品推荐
相关产品推荐

