Add: First implementation of Button, to create Whisper Chat
This commit is contained in:
@@ -3,6 +3,7 @@ package ch.unibas.dmi.dbis.cs108.casono.client.chat;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.network.ChatClient;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.ui.chatui.ChatBoxController;
|
||||
import javafx.application.Platform;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.Timer;
|
||||
@@ -55,8 +56,10 @@ public class ChatController {
|
||||
new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
clientService.ping();
|
||||
receiveMessage();
|
||||
Platform.runLater(() -> {
|
||||
clientService.ping();
|
||||
receiveMessage();
|
||||
});
|
||||
}
|
||||
},
|
||||
0,
|
||||
@@ -67,6 +70,7 @@ public class ChatController {
|
||||
this.lobbyId = lobbyId;
|
||||
ChatModel lobbyChatModel = new ChatModel(ChatType.LOBBY, username, lobbyId, null);
|
||||
chatModelMap.put(new ChatKey(ChatType.LOBBY), lobbyChatModel);
|
||||
this.chatBoxController.addChatTab("Lobby", lobbyChatModel);
|
||||
}
|
||||
|
||||
/** method to get all messages from the server */
|
||||
@@ -89,9 +93,7 @@ public class ChatController {
|
||||
if (chatModelMap.containsKey(new ChatKey(ChatType.WHISPER, msg.sender))) {
|
||||
chatModelMap.get(new ChatKey(ChatType.WHISPER, msg.sender)).addMessage(msg);
|
||||
} else {
|
||||
ChatModel value = new ChatModel(ChatType.WHISPER, username, -1, msg.sender);
|
||||
chatModelMap.put(new ChatKey(ChatType.WHISPER, msg.sender), value);
|
||||
chatBoxController.addWhisperChat(msg.sender, value);
|
||||
chatBoxController.addWhisperChat(msg.sender);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
+22
-4
@@ -5,12 +5,16 @@ import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatModel;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatType;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.MenuButton;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
public class ChatBoxController {
|
||||
|
||||
@@ -22,8 +26,12 @@ public class ChatBoxController {
|
||||
|
||||
@FXML private TabPane ChatTabPane;
|
||||
|
||||
@FXML private MenuButton addWhisperChatButton;
|
||||
|
||||
private FXMLLoader fxmlLoader;
|
||||
|
||||
@FXML private List<MenuItem> whisperUsers;
|
||||
|
||||
private String ressource = "/ui-structure/components/chatui/chattab.fxml";
|
||||
|
||||
|
||||
@@ -41,7 +49,16 @@ public class ChatBoxController {
|
||||
}
|
||||
|
||||
|
||||
public void addWhisperChat(String target, ChatModel chatModel) {
|
||||
public void addWhisperUser(String targetUserName) {
|
||||
MenuItem menuItem = new MenuItem(targetUserName);
|
||||
whisperUsers.add(menuItem);
|
||||
addWhisperChatButton.getItems().add(menuItem);
|
||||
|
||||
menuItem.setOnAction(event -> addWhisperChat(targetUserName));
|
||||
}
|
||||
|
||||
public void addWhisperChat(String target) {
|
||||
ChatModel chatModel = new ChatModel(ChatType.WHISPER, username, -1, target);
|
||||
chatController.getChatModelMap().put(new ChatController.ChatKey(ChatType.WHISPER, target), chatModel);
|
||||
addChatTab(target, chatModel);
|
||||
}
|
||||
@@ -50,11 +67,12 @@ public class ChatBoxController {
|
||||
public void addChatTab(String title, ChatModel chatModel) {
|
||||
URL resource = getClass().getResource(ressource);
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(resource);
|
||||
ChatViewController chatViewController = new ChatViewController(username, chatModel, chatController);
|
||||
chatModel.addListener((msg)-> chatViewController.showMessage(msg));
|
||||
try {
|
||||
ChatViewController chatViewController = new ChatViewController(this.chatController, chatModel, this.username);
|
||||
fxmlLoader.setController(chatViewController);
|
||||
Tab newChat = new Tab(title, fxmlLoader.load());
|
||||
Node load = fxmlLoader.load();
|
||||
chatModel.addListener((msg)-> chatViewController.showMessage(msg));
|
||||
Tab newChat = new Tab(title, load);
|
||||
this.ChatTabPane.getTabs().add(newChat);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
+3
-9
@@ -38,23 +38,17 @@ public class ChatViewController implements Initializable {
|
||||
|
||||
private static final int CHAT_PADDING = 20;
|
||||
|
||||
public ChatViewController() {
|
||||
this(null, null, null);
|
||||
}
|
||||
|
||||
public ChatViewController(
|
||||
String username, ChatModel chatModel, ChatController controller) {
|
||||
public ChatViewController(ChatController chatController, ChatModel chatModel, String username){
|
||||
this.controller = chatController;
|
||||
this.username = username;
|
||||
this.controller = controller;
|
||||
this.chatModel = chatModel;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resourceBundle) {
|
||||
inputField.setOnAction(event -> sendMessage());
|
||||
sendButton.setOnAction(event -> sendMessage());
|
||||
scrollPane.vvalueProperty().bind(chatInterfaceVBox.heightProperty());
|
||||
scrollPane.vvalueProperty().bind(chat.heightProperty());
|
||||
}
|
||||
|
||||
public void sendMessage() {
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
|
||||
<!-- fx:controller="ch.unibas.dmi.dbis.cs108.casono.client.ui.chatui.ChatBoxController" -->
|
||||
|
||||
<?import javafx.scene.control.skin.SplitPaneSkin.Content?>
|
||||
<?import com.sun.javafx.scene.control.ContextMenuContent.MenuBox?>
|
||||
<VBox xmlns="http://javafx.com/javafx/21"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:id="chatBox"
|
||||
@@ -20,11 +21,14 @@
|
||||
<children>
|
||||
<Label text="== CHAT ==" styleClass="chat-header" alignment="CENTER" maxWidth="Infinity"/>
|
||||
<Region minHeight="4" styleClass="chat-separator"/>
|
||||
<MenuButton fx:id="addWhisperChatButton" styleClass="gray-button" text="+" alignment="CENTER_RIGHT">
|
||||
</MenuButton>
|
||||
</children>
|
||||
|
||||
</HBox>
|
||||
|
||||
<TabPane fx:id="ChatTabPane">
|
||||
|
||||
</TabPane>
|
||||
|
||||
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import java.util.*?>
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<!-- VBox for the global chat, should only be visible when activated via changeGlobalChatButton-->
|
||||
<VBox xmlns="http://javafx.com/javafx/21"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:id="chatInterfaceVBox"
|
||||
|
||||
<VBox fx:id="chatInterfaceVBox"
|
||||
maxWidth="Infinity"
|
||||
minHeight="500"
|
||||
spacing="10"
|
||||
styleClass="chat-box"
|
||||
stylesheets="@chatui.css"
|
||||
styleClass="chat-box">
|
||||
VBox.vgrow="ALWAYS"
|
||||
xmlns="http://javafx.com/javafx/17.0.12"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
>
|
||||
|
||||
<children>
|
||||
<!-- Chatnachrichten werden hier hinzugefügt -->
|
||||
<ScrollPane fx:id="scrollPane" fitToWidth="true" vbarPolicy="AS_NEEDED" hbarPolicy="NEVER" styleClass="chat-scroll-pane" VBox.vgrow="ALWAYS">
|
||||
<content>
|
||||
<VBox fx:id="chat" spacing="10" styleClass="chat-VBox" />
|
||||
</content>
|
||||
</ScrollPane>
|
||||
|
||||
<!-- Eingabebereich -->
|
||||
<HBox fx:id="controlBar" spacing="10">
|
||||
<!-- TODO: Größe des TextFields dynamisch anpassen -->
|
||||
<TextField fx:id="inputField" promptText="Nachricht eingeben..." styleClass="gray-input-field" HBox.hgrow="ALWAYS" />
|
||||
<Button fx:id="sendButton" styleClass="yellow-button" text="SENDEN" />
|
||||
</HBox>
|
||||
</children>
|
||||
|
||||
|
||||
<!-- Chatnachrichten werden hier hinzugefügt -->
|
||||
<ScrollPane fx:id="scrollPane" fitToWidth="true" vbarPolicy="AS_NEEDED" hbarPolicy="NEVER"
|
||||
VBox.vgrow="ALWAYS" styleClass="chat-scroll-pane">
|
||||
<content>
|
||||
<VBox fx:id="chat" spacing="10" styleClass="chat-VBox"/>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
|
||||
<!-- Eingabebereich -->
|
||||
<HBox spacing="10"
|
||||
fx:id="controlBar">
|
||||
<!-- TODO: Größe des TextFields dynamisch anpassen -->
|
||||
<TextField fx:id="inputField" HBox.hgrow="ALWAYS" promptText="Nachricht eingeben..."
|
||||
styleClass="gray-input-field"/>
|
||||
<Button fx:id="sendButton" text="SENDEN"
|
||||
styleClass="yellow-button"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
||||
|
||||
@@ -153,3 +153,12 @@
|
||||
.scroll-pane .scroll-bar:horizontal .thumb:hover {
|
||||
-fx-pref-height: 10;
|
||||
}
|
||||
|
||||
.tab-pane .tab-header-area {
|
||||
-fx-background-color: #0d763b;
|
||||
}
|
||||
|
||||
.tab .tab-label {
|
||||
-fx-font-family: "Courier New";
|
||||
-fx-font-weight: bold;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<!--
|
||||
Dieses Fenster wird später mit den Serveranfragen verknüpft,
|
||||
um Nachrichten von Mitspielern und Systemmeldungen in Echtzeit anzuzeigen.
|
||||
|
||||
Der Chat unterscheidet intern zwischen:
|
||||
- Player-to-Player (Privater 2-Personen-Chat)
|
||||
- Lobby-Chat (Aktueller Raum)
|
||||
- Globaler Chat (Gesamter Server)
|
||||
|
||||
Features, die später implementiert werden sollen:
|
||||
- Schicke Chat-Bubbles mit Namen und Uhrzeit.
|
||||
-->
|
||||
|
||||
<VBox xmlns="http://javafx.com/javafx/21"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="ch.unibas.dmi.dbis.cs108.casono.client.ui.chatui.ChatViewController"
|
||||
alignment="CENTER"
|
||||
stylesheets="@chatui.css">
|
||||
|
||||
<!-- Innenabstand: Schafft oben, rechts und unten 30 Pixel Platz, links nur 10 Pixel (asymmetrisch) -->
|
||||
<padding>
|
||||
<Insets top="30" right="30" bottom="30" left="10"/>
|
||||
</padding>
|
||||
|
||||
<children>
|
||||
<VBox VBox.vgrow="ALWAYS"
|
||||
styleClass="chat-box"
|
||||
spacing="10"
|
||||
maxWidth="Infinity">
|
||||
|
||||
<children>
|
||||
<Label text="== CHAT ==" styleClass="chat-header" alignment="CENTER" maxWidth="Infinity"/>
|
||||
<Region minHeight="4" styleClass="chat-separator"/>
|
||||
|
||||
<!-- Chatnachrichten werden hier hinzugefügt -->
|
||||
<ScrollPane fx:id="chatScrollPane" fitToWidth="true" vbarPolicy="AS_NEEDED" hbarPolicy="NEVER" VBox.vgrow="ALWAYS" styleClass="chat-scroll-pane">
|
||||
<content>
|
||||
<VBox fx:id="chatVBox" spacing="10" styleClass="chat-VBox"/>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
|
||||
<!-- Eingabebereich -->
|
||||
<HBox spacing="10">
|
||||
<!-- TODO: Größe des TextFields dynamisch anpassen -->
|
||||
<TextField fx:id="inputField" HBox.hgrow="ALWAYS" promptText="Nachricht eingeben..." styleClass="gray-input-field" onAction="#sendMessage"/>
|
||||
<Button fx:id="sendButton" text="SENDEN" onAction="#sendMessage" styleClass="yellow-button"/>
|
||||
<Button fx:id="refreshButton" text="NEU" onAction="#showMessage" styleClass="yellow-button"/>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</VBox>
|
||||
@@ -1,155 +0,0 @@
|
||||
.chat-box {
|
||||
-fx-background-color: #0d9e3b;
|
||||
-fx-background-radius: 58;
|
||||
-fx-border-radius: 50;
|
||||
-fx-border-color: #5c3d10 #3d260a #3d260a #5c3d10;
|
||||
-fx-border-width: 12;
|
||||
-fx-padding: 20;
|
||||
-fx-effect: dropshadow(one-pass-box, rgba(0,0,0,1), 0, 0, 15, 15);
|
||||
}
|
||||
|
||||
.chat-header {
|
||||
-fx-text-fill: #ffffff;
|
||||
-fx-font-size: 22px;
|
||||
-fx-font-weight: bold;
|
||||
-fx-padding: 0 0 10 0;
|
||||
-fx-effect: dropshadow(one-pass-box, #000000, 0, 0, 3, 3);
|
||||
}
|
||||
|
||||
.chat-separator {
|
||||
-fx-background-color: #ffffff;
|
||||
-fx-min-height: 4px;
|
||||
-fx-effect: dropshadow(one-pass-box, #000000, 0, 0, 3, 3);
|
||||
}
|
||||
|
||||
.black-input-field {
|
||||
-fx-background-color: #1a1a1a;
|
||||
-fx-text-fill: #ffffff;
|
||||
-fx-font-family: "Courier New";
|
||||
-fx-font-weight: bold;
|
||||
-fx-background-radius: 8;
|
||||
-fx-border-radius: 8;
|
||||
-fx-border-color: #444444;
|
||||
-fx-border-width: 2;
|
||||
-fx-padding: 5 12;
|
||||
}
|
||||
|
||||
.black-input-field:hover {
|
||||
-fx-translate-y: -3;
|
||||
-fx-effect: dropshadow(one-pass-box, rgba(0, 0, 0, 0.8), 0, 0, 3, 3);
|
||||
}
|
||||
|
||||
|
||||
.black-input-field:focused {
|
||||
-fx-border-color: #ffffff;
|
||||
-fx-background-color: #000000;
|
||||
}
|
||||
|
||||
.gray-input-field {
|
||||
-fx-background-color: #333333;
|
||||
-fx-text-fill: #ffffff;
|
||||
-fx-font-family: "Courier New";
|
||||
-fx-font-weight: bold;
|
||||
-fx-background-radius: 8;
|
||||
-fx-border-radius: 8;
|
||||
-fx-border-color: #666666;
|
||||
-fx-color-color: #cccccc;
|
||||
-fx-border-width: 2;
|
||||
-fx-padding: 5 12;
|
||||
}
|
||||
|
||||
.gray-input-field:hover {
|
||||
-fx-translate-y: -3;
|
||||
-fx-effect: dropshadow(one-pass-box, rgba(0, 0, 0, 0.8), 0, 0, 3, 3);
|
||||
}
|
||||
|
||||
.gray-input-field:focused {
|
||||
-fx-border-color: #ffffff;
|
||||
-fx-background-color: #333333;
|
||||
}
|
||||
|
||||
.yellow-button {
|
||||
-fx-background-color: #b8860b;
|
||||
-fx-border-color: #ffd700;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
|
||||
.red-button {
|
||||
-fx-background-color: #8b0000;
|
||||
-fx-border-color: #ff4444;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
|
||||
.gray-button {
|
||||
-fx-background-color: #333333;
|
||||
-fx-border-color: #666666;
|
||||
-fx-text-fill: #cccccc;
|
||||
}
|
||||
|
||||
.gray-button, .yellow-button, .red-button {
|
||||
-fx-background-radius: 12;
|
||||
-fx-border-radius: 12;
|
||||
-fx-font-family: "Courier New";
|
||||
-fx-font-weight: bold;
|
||||
-fx-border-width: 2;
|
||||
-fx-padding: 6 15;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
.gray-button:hover, .yellow-button:hover, .red-button:hover {
|
||||
-fx-translate-y: -3;
|
||||
-fx-effect: dropshadow(one-pass-box, rgba(0, 0, 0, 0.8), 0, 0, 3, 3);
|
||||
}
|
||||
|
||||
.chat-scroll-pane {
|
||||
-fx-background-color: transparent;
|
||||
-fx-background: transparent;
|
||||
-fx-border-color: transparent;
|
||||
}
|
||||
|
||||
.chat-VBox {
|
||||
-fx-background-color: transparent;
|
||||
-fx-background: transparent;
|
||||
}
|
||||
.scroll-pane {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-color: transparent;
|
||||
}
|
||||
|
||||
.scroll-pane .scroll-bar:vertical {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.scroll-pane .scroll-bar .track {
|
||||
-fx-background-color: #5c3d10;
|
||||
-fx-background-insets: 0;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
.scroll-pane .scroll-bar .thumb {
|
||||
-fx-background-color: #3d260a;
|
||||
-fx-background-insets: 0;
|
||||
-fx-background-radius: 5;
|
||||
-fx-pref-width: 6;
|
||||
-fx-pref-height: 6;
|
||||
-fx-padding: 0;
|
||||
}
|
||||
|
||||
.scroll-pane .scroll-bar:horizontal {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.scroll-pane .scroll-bar:horizontal .track {
|
||||
-fx-background-color: #5c3d10;
|
||||
-fx-background-radius: 5;
|
||||
}
|
||||
|
||||
.scroll-pane .scroll-bar:horizontal .thumb {
|
||||
-fx-background-color: #3d260a;
|
||||
-fx-background-radius: 5;
|
||||
-fx-pref-height: 6;
|
||||
}
|
||||
|
||||
.scroll-pane .scroll-bar:horizontal .thumb:hover {
|
||||
-fx-pref-height: 10;
|
||||
}
|
||||
Reference in New Issue
Block a user