I’m developing a board game in JavaFX where a player can move a piece and then an AI bot makes its move. The game is designed such that when the human player releases a piece at any point on a valid square then the piece will automatically be snapped to the center of the square. However, I’m experiencing an issue where the piece’s position isn’t updated on the UI until after the bot finishes its move decision.

Here’s a simplified version of my code:

pieceComp.getEllipse().setOnMouseReleased(e -> {
    // Process the move
    int newRow = toBoardPos(pieceComp.getLayoutY());
    int newCol = toBoardPos(pieceComp.getLayoutX());
    Move move = new Move(game.getBoard()[oldRow][oldCol], game.getBoard()[newRow][newCol]);
    MoveResult moveResult = game.processMove(move);

    if (moveResult.isValidMove()) {
        pieceComp.move(newRow, newCol); // this is where the piece is relocated
        switchPlayer();
        if (game.getCurrentPlayer() instanceof BotPlayer) {
            new Thread(() -> Platform.runLater(this::botMakeMove)).start();
        }
    } else {
        pieceComp.abortMove();
    }
});

In the botMakeMove() method, the bot decides its move which takes about 2-3 seconds. I’ve tried running botMakeMove() on a separate thread to prevent it from blocking the UI thread, but the issue persists.

I have also ensured that there are no other long-running or blocking operations happening on the UI thread.

I’ve also checked that pieceComp.move(newRow, newCol); is being called before botMakeMove(), but its UI changes aren’t appearing until after botMakeMove() finishes.

Any insights into why the piece’s position isn’t updating immediately, and how I can resolve this issue?

Edit: I forgot to mention that the botMakeMove() method would also update the UI (as the bot makes its move)

7

Resolved: Delay in UI Update When Moving Piece in JavaFX Board Game.

I managed to resolve the issue with a great suggestion from @SedJ601.

The solution was to use a javafx.concurrent.Task to run the bot’s decision-making process on a separate thread. This allowed the UI to update immediately after the player’s move, while the bot’s move was being decided.

Here’s the modified botMakeMove() method:

private void botMakeMove() {
    // Create a new Task
    Task<Move> botMoveTask = new Task<>() {
        @Override
        protected Move call() {
            // Perform the long-running operation (bot deciding its move)
            BotPlayer botPlayer = (BotPlayer) game.getCurrentPlayer();
            Move botMove = botPlayer.getBestMove((GameWithBot) game);
            return botMove;
        }
    };

    // Set up what to do when the Task is done
    botMoveTask.setOnSucceeded(event -> {
        // Get the result of the Task
        Move botMove = botMoveTask.getValue();

        // Update the UI according to the bot's move...
        switchPlayer();
    });

    // Start the Task on a new Thread
    new Thread(botMoveTask).start();
}

This approach ensures that the bot’s decision-making process doesn’t block the UI thread, allowing the piece to snap to its position immediately when released, even though the bot is still deciding its move.

I hope this helps anyone else who’s facing a similar issue!

2