From 56ebe1347c71b7781d1afd25ba667789176fdba9 Mon Sep 17 00:00:00 2001 From: ramollia <@> Date: Wed, 15 Oct 2025 16:13:42 +0200 Subject: [PATCH] add: server chat box --- app/src/main/java/org/toop/app/Server.java | 12 ++++-- .../org/toop/app/canvas/ReversiCanvas.java | 24 ++++++------ .../java/org/toop/app/game/ReversiGame.java | 13 +++++-- .../java/org/toop/app/game/TicTacToeGame.java | 13 +++++-- .../org/toop/app/view/views/GameView.java | 39 +++++++++++++++++-- .../app/view/views/LocalMultiplayerView.java | 4 +- 6 files changed, 76 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/org/toop/app/Server.java b/app/src/main/java/org/toop/app/Server.java index 68facb4..8ec565a 100644 --- a/app/src/main/java/org/toop/app/Server.java +++ b/app/src/main/java/org/toop/app/Server.java @@ -116,8 +116,8 @@ public final class Server { information.players[1].name = opponent; switch (type) { - case TICTACTOE: new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame); break; - case REVERSI: new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame); break; + case TICTACTOE: new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage); break; + case REVERSI: new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage); break; } } }).postEvent(); @@ -159,14 +159,18 @@ public final class Server { information.players[1].name = e.opponent(); switch (type) { - case TICTACTOE: new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame); break; - case REVERSI: new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame); break; + case TICTACTOE: new TicTacToeGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage); break; + case REVERSI: new ReversiGame(information, myTurn, this::forfeitGame, this::exitGame, this::sendMessage); break; } } }); })); } + private void sendMessage(String message) { + new EventFlow().addPostEvent(new NetworkEvents.SendMessage(clientId, message)).postEvent(); + } + private void disconnect() { new EventFlow().addPostEvent(new NetworkEvents.CloseClient(clientId)).postEvent(); ViewStack.push(new OnlineView()); diff --git a/app/src/main/java/org/toop/app/canvas/ReversiCanvas.java b/app/src/main/java/org/toop/app/canvas/ReversiCanvas.java index 0000bbf..277937c 100644 --- a/app/src/main/java/org/toop/app/canvas/ReversiCanvas.java +++ b/app/src/main/java/org/toop/app/canvas/ReversiCanvas.java @@ -4,11 +4,11 @@ import javafx.scene.paint.Color; import java.util.function.Consumer; -public class ReversiCanvas extends GameCanvas{ - public ReversiCanvas(Color color, int width, int height, Consumer onCellClicked) { - super(color, width, height, 8, 8, 10, true, onCellClicked); - drawStartingDots(); - } +public final class ReversiCanvas extends GameCanvas { + public ReversiCanvas(Color color, int width, int height, Consumer onCellClicked) { + super(color, width, height, 8, 8, 10, true, onCellClicked); + drawStartingDots(); + } public void drawDot(Color color, int cell) { final float x = cells[cell].x() + gapSize; @@ -21,14 +21,14 @@ public class ReversiCanvas extends GameCanvas{ graphics.fillOval(x, y, width, height); } - public void drawStartingDots() { - drawDot(Color.BLACK, 28); - drawDot(Color.WHITE, 36); - drawDot(Color.BLACK, 35); - drawDot(Color.WHITE, 27); - } + public void drawStartingDots() { + drawDot(Color.BLACK, 28); + drawDot(Color.WHITE, 36); + drawDot(Color.BLACK, 35); + drawDot(Color.WHITE, 27); + } public void drawLegalPosition(int cell) { drawDot(new Color(1.0f, 0.0f, 0.0f, 0.5f), cell); } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/game/ReversiGame.java b/app/src/main/java/org/toop/app/game/ReversiGame.java index 2e0f92b..a776e5c 100644 --- a/app/src/main/java/org/toop/app/game/ReversiGame.java +++ b/app/src/main/java/org/toop/app/game/ReversiGame.java @@ -17,6 +17,7 @@ import javafx.scene.paint.Color; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Consumer; public final class ReversiGame { private final GameInformation information; @@ -30,7 +31,7 @@ public final class ReversiGame { private final GameView view; private final ReversiCanvas canvas; - public ReversiGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit) { + public ReversiGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer onMessage) { this.information = information; this.myTurn = myTurn; @@ -42,9 +43,9 @@ public final class ReversiGame { if (onForfeit == null || onExit == null) { view = new GameView(null, () -> { ViewStack.push(new LocalMultiplayerView(information)); - }); + }, null); } else { - view = new GameView(onForfeit, onExit); + view = new GameView(onForfeit, onExit, onMessage); } canvas = new ReversiCanvas(Color.GRAY, @@ -86,6 +87,10 @@ public final class ReversiGame { updateCanvas(); } + public ReversiGame(GameInformation information) { + this(information, 0, null, null, null); + } + private void localGameThread() { boolean isRunning = true; @@ -197,7 +202,7 @@ public final class ReversiGame { } private void onReceivedMessage(NetworkEvents.ReceivedMessage msg) { - view.updateChat("anon", msg.message()); + view.updateChat(msg.message()); } private void updateCanvas() { diff --git a/app/src/main/java/org/toop/app/game/TicTacToeGame.java b/app/src/main/java/org/toop/app/game/TicTacToeGame.java index 07f589a..0ac764d 100644 --- a/app/src/main/java/org/toop/app/game/TicTacToeGame.java +++ b/app/src/main/java/org/toop/app/game/TicTacToeGame.java @@ -17,6 +17,7 @@ import javafx.scene.paint.Color; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Consumer; public final class TicTacToeGame { private final GameInformation information; @@ -30,7 +31,7 @@ public final class TicTacToeGame { private final GameView view; private final TicTacToeCanvas canvas; - public TicTacToeGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit) { + public TicTacToeGame(GameInformation information, int myTurn, Runnable onForfeit, Runnable onExit, Consumer onMessage) { this.information = information; this.myTurn = myTurn; @@ -42,9 +43,9 @@ public final class TicTacToeGame { if (onForfeit == null || onExit == null) { view = new GameView(null, () -> { ViewStack.push(new LocalMultiplayerView(information)); - }); + }, null); } else { - view = new GameView(onForfeit, onExit); + view = new GameView(onForfeit, onExit, onMessage); } canvas = new TicTacToeCanvas(Color.GRAY, @@ -84,6 +85,10 @@ public final class TicTacToeGame { } } + public TicTacToeGame(GameInformation information) { + this(information, 0, null, null, null); + } + private void localGameThread() { boolean isRunning = true; @@ -205,7 +210,7 @@ public final class TicTacToeGame { } private void onReceivedMessage(NetworkEvents.ReceivedMessage msg) { - view.updateChat("anon", msg.message()); + view.updateChat(msg.message()); } private void setGameLabels(boolean isMe) { diff --git a/app/src/main/java/org/toop/app/view/views/GameView.java b/app/src/main/java/org/toop/app/view/views/GameView.java index e8f12cb..d6fe0f7 100644 --- a/app/src/main/java/org/toop/app/view/views/GameView.java +++ b/app/src/main/java/org/toop/app/view/views/GameView.java @@ -6,8 +6,12 @@ import org.toop.local.AppContext; import javafx.geometry.Pos; import javafx.scene.control.Button; +import javafx.scene.control.ListView; +import javafx.scene.control.TextField; import javafx.scene.text.Text; +import java.util.function.Consumer; + public final class GameView extends View { private static class GameOverView extends View { private final boolean iWon; @@ -65,7 +69,10 @@ public final class GameView extends View { private final Text nextPlayerHeader; - public GameView(Runnable onForfeit, Runnable onExit) { + private final ListView chatListView; + private final TextField chatInput; + + public GameView(Runnable onForfeit, Runnable onExit, Consumer onMessage) { assert onExit != null; super(true, "bg-primary"); @@ -78,6 +85,16 @@ public final class GameView extends View { forfeitButton = null; } + if (onMessage != null) { + chatListView = new ListView(); + + chatInput = input(); + chatInput.setOnAction(_ -> onMessage.accept(chatInput.getText())); + } else { + chatListView = null; + chatInput = null; + } + exitButton = button(); exitButton.setText(AppContext.getString("exit")); exitButton.setOnAction(_ -> onExit.run()); @@ -110,6 +127,15 @@ public final class GameView extends View { exitButton ) ); + + if (chatListView != null) { + add(Pos.BOTTOM_RIGHT, + fit(vboxFill( + chatListView, + chatInput + ) + )); + } } public void nextPlayer(boolean isMe, String currentPlayer, String currentMove, String nextPlayer) { @@ -125,8 +151,15 @@ public final class GameView extends View { } } - public void updateChat(String player, String message) { - // Todo + public void updateChat(String message) { + if (chatListView == null) { + return; + } + + final Text messageText = text(); + messageText.setText(message); + + chatListView.getItems().add(messageText); } public void gameOver(boolean iWon, String winner) { diff --git a/app/src/main/java/org/toop/app/view/views/LocalMultiplayerView.java b/app/src/main/java/org/toop/app/view/views/LocalMultiplayerView.java index bafcaae..a4e72d9 100644 --- a/app/src/main/java/org/toop/app/view/views/LocalMultiplayerView.java +++ b/app/src/main/java/org/toop/app/view/views/LocalMultiplayerView.java @@ -43,8 +43,8 @@ public final class LocalMultiplayerView extends View { } switch (information.type) { - case TICTACTOE: new TicTacToeGame(information, 0, null, null); break; - case REVERSI: new ReversiGame(information, 0, null, null); break; + case TICTACTOE: new TicTacToeGame(information); break; + case REVERSI: new ReversiGame(information); break; } });