Merge 'feat/lobby-ui' back into 'main' #172
@@ -36,6 +36,7 @@ dependencies {
|
|||||||
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
|
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.10.0")
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.10.0")
|
||||||
|
implementation 'org.json:json:20240303'
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
|||||||
@@ -3,8 +3,25 @@ package ch.unibas.dmi.dbis.cs108.casono;
|
|||||||
import ch.unibas.dmi.dbis.cs108.casono.client.ClientApp;
|
import ch.unibas.dmi.dbis.cs108.casono.client.ClientApp;
|
||||||
import ch.unibas.dmi.dbis.cs108.casono.server.ServerApp;
|
import ch.unibas.dmi.dbis.cs108.casono.server.ServerApp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point for Casono application.
|
||||||
|
* Handles client and server startup.
|
||||||
|
* <p>
|
||||||
|
* Standardkonstruktor für die Anwendung.
|
||||||
|
*/
|
||||||
public final class Main {
|
public final class Main {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standardkonstruktor.
|
||||||
|
*/
|
||||||
|
public Main() {
|
||||||
|
// Standardkonstruktor
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point for Casono.
|
||||||
|
* @param args Command line arguments
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
if (!isValid(args)) {
|
if (!isValid(args)) {
|
||||||
printUsage();
|
printUsage();
|
||||||
|
|||||||
@@ -1,6 +1,29 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.casono.client;
|
package ch.unibas.dmi.dbis.cs108.casono.client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for the Casono client application.
|
||||||
|
* Handles client startup and connection parameters.
|
||||||
|
*/
|
||||||
|
import ch.unibas.dmi.dbis.cs108.casono.client.ui.Launcher;
|
||||||
|
/**
|
||||||
|
* Entry point for the Casono client application.
|
||||||
|
* Handles client startup and connection parameters.
|
||||||
|
* <p>
|
||||||
|
* Standardkonstruktor für die Anwendung.
|
||||||
|
*/
|
||||||
public class ClientApp {
|
public class ClientApp {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standardkonstruktor.
|
||||||
|
*/
|
||||||
|
public ClientApp() {
|
||||||
|
// Standardkonstruktor
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Starts the client application with the given address.
|
||||||
|
* @param arg Address in the format "ip:port".
|
||||||
|
* @throws IllegalArgumentException if the address format is invalid.
|
||||||
|
*/
|
||||||
public static void start(String arg) {
|
public static void start(String arg) {
|
||||||
String[] parts = arg.split(":", 2);
|
String[] parts = arg.split(":", 2);
|
||||||
if (parts.length != 2) {
|
if (parts.length != 2) {
|
||||||
@@ -10,5 +33,6 @@ public class ClientApp {
|
|||||||
int port = Integer.parseInt(parts[1]);
|
int port = Integer.parseInt(parts[1]);
|
||||||
|
|
||||||
System.out.println("You've selected the client. It will connect port " + port + " at host " + host);
|
System.out.println("You've selected the client. It will connect port " + port + " at host " + host);
|
||||||
|
Launcher.main(new String[]{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.client.ui;
|
||||||
|
|
||||||
|
import javafx.application.Application;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launcher for the Casono main UI.
|
||||||
|
* <p>
|
||||||
|
* Standardkonstruktor für die Anwendung.
|
||||||
|
*/
|
||||||
|
public class Launcher {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standardkonstruktor.
|
||||||
|
*/
|
||||||
|
public Launcher() {
|
||||||
|
// Standardkonstruktor
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Main entry point for launching the UI.
|
||||||
|
* @param args Command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Application.launch(ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui.Casinomainui.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main UI application for Casono.
|
||||||
|
* Loads the main FXML layout and sets up the stage.
|
||||||
|
*/
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JavaFX Application class for the Casono main UI.
|
||||||
|
* <p>
|
||||||
|
* Standardkonstruktor für die Anwendung.
|
||||||
|
*/
|
||||||
|
public class Casinomainui extends Application {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standardkonstruktor.
|
||||||
|
*/
|
||||||
|
public Casinomainui() {
|
||||||
|
// Standardkonstruktor
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
/**
|
||||||
|
* Starts the JavaFX application and loads the main UI.
|
||||||
|
* @param stage The primary stage for this application.
|
||||||
|
* @throws IOException If loading the FXML fails.
|
||||||
|
*/
|
||||||
|
public void start(Stage stage) throws IOException {
|
||||||
|
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/ui-structure/Casinomainui.fxml"));
|
||||||
|
Scene scene = new Scene(fxmlLoader.load(), 1200, 800);
|
||||||
|
stage.setTitle("Casono");
|
||||||
|
|
||||||
|
stage.getIcons().add(new javafx.scene.image.Image(getClass().getResource("/images/logoinverted.png").toExternalForm()));
|
||||||
|
stage.setScene(scene);
|
||||||
|
stage.setFullScreen(true);
|
||||||
|
stage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point for launching the application.
|
||||||
|
* @param args Command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
launch();
|
||||||
|
}
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.scene.shape.Rectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the Casono main UI lobby.
|
||||||
|
* Handles UI initialization and user actions.
|
||||||
|
*/
|
||||||
|
public class CasinomainuiController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private AnchorPane rootPane;
|
||||||
|
@FXML
|
||||||
|
private Label titleLabel;
|
||||||
|
@FXML
|
||||||
|
private Label subtitleLabel;
|
||||||
|
@FXML
|
||||||
|
private ImageView logoView;
|
||||||
|
@FXML
|
||||||
|
private Rectangle greenBox;
|
||||||
|
@FXML
|
||||||
|
private Button exitbutton;
|
||||||
|
@FXML
|
||||||
|
private VBox casinoTable;
|
||||||
|
|
||||||
|
private LobbyButtonTranslationManager translationManager;
|
||||||
|
private LobbyButtonGridManager gridManager;
|
||||||
|
private int nextButtonId = 1;
|
||||||
|
|
||||||
|
public CasinomainuiController() {
|
||||||
|
// Default constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the UI components and sets default values.
|
||||||
|
*/
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
titleLabel.setText("Casono");
|
||||||
|
subtitleLabel.setText("Texas Hold'em Poker");
|
||||||
|
logoView.setImage(new Image(getClass().getResource("/images/logo.png").toExternalForm()));
|
||||||
|
|
||||||
|
translationManager = new LobbyButtonTranslationManager();
|
||||||
|
gridManager = new LobbyButtonGridManager(new javafx.scene.layout.GridPane(), translationManager);
|
||||||
|
casinoTable.getChildren().clear();
|
||||||
|
casinoTable.getChildren().add(gridManager.getGridPane());
|
||||||
|
gridManager.renderLobbyButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the exit button action to close the application.
|
||||||
|
*/
|
||||||
|
@FXML
|
||||||
|
public void handleexitbutton() {
|
||||||
|
Platform.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles creation of a new lobby button.
|
||||||
|
*/
|
||||||
|
@FXML
|
||||||
|
public void handleCreateLobbyButton() {
|
||||||
|
if (translationManager.isFull()) {
|
||||||
|
System.out.println("Grid voll! Keine weiteren Lobbys moeglich.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int buttonId = nextButtonId++;
|
||||||
|
int lobbyId = gridManager.createLobby();
|
||||||
|
try {
|
||||||
|
translationManager.addLobbyButton(buttonId, lobbyId);
|
||||||
|
System.out.println("ButtonID: " + buttonId + ", LobbyID: " + lobbyId);
|
||||||
|
gridManager.renderLobbyButtons();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Fehler beim Hinzufügen: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+101
@@ -0,0 +1,101 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the grid for lobby buttons and rendering.
|
||||||
|
* Uses LobbyButtonTranslationManager for mapping ButtonID to LobbyID.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the grid for lobby buttons and rendering.
|
||||||
|
* Uses LobbyButtonTranslationManager for mapping ButtonID to LobbyID.
|
||||||
|
*/
|
||||||
|
public class LobbyButtonGridManager {
|
||||||
|
|
||||||
|
/** GridPane for the button grid. */
|
||||||
|
private final GridPane gridPane;
|
||||||
|
/** Manager for mapping ButtonID to LobbyID. */
|
||||||
|
private final LobbyButtonTranslationManager translationManager;
|
||||||
|
/** Number of rows in the grid. */
|
||||||
|
private final int rows = 2;
|
||||||
|
/** Number of columns in the grid. */
|
||||||
|
private final int cols = 4;
|
||||||
|
/** Path to the button image. */
|
||||||
|
private final String buttonImagePath = "/images/logo.png";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the GridManager.
|
||||||
|
*
|
||||||
|
* @param gridPane the GridPane for rendering
|
||||||
|
* @param translationManager the manager for mapping ButtonID to LobbyID
|
||||||
|
*/
|
||||||
|
public LobbyButtonGridManager(GridPane gridPane, LobbyButtonTranslationManager translationManager) {
|
||||||
|
this.gridPane = gridPane;
|
||||||
|
this.translationManager = translationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders all lobby buttons in the grid.
|
||||||
|
* Creates a button for each mapping with image and event handler.
|
||||||
|
*/
|
||||||
|
public void renderLobbyButtons() {
|
||||||
|
gridPane.getChildren().clear();
|
||||||
|
int index = 0;
|
||||||
|
Map<Integer, Integer> mapping = translationManager.getButtonIdToLobbyId();
|
||||||
|
if (mapping.isEmpty()) {
|
||||||
|
// No buttons to render
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Map.Entry<Integer, Integer> entry : mapping.entrySet()) {
|
||||||
|
int buttonId = entry.getKey();
|
||||||
|
Button btn = new Button();
|
||||||
|
btn.setId("lobbyBtn-" + buttonId);
|
||||||
|
btn.setGraphic(new ImageView(new Image(getClass().getResourceAsStream(buttonImagePath))));
|
||||||
|
btn.setOnAction(e -> {
|
||||||
|
Integer lobbyId = translationManager.getLobbyIdForButton(buttonId);
|
||||||
|
if (lobbyId != null)
|
||||||
|
joinLobby(lobbyId);
|
||||||
|
});
|
||||||
|
int row = index / cols;
|
||||||
|
int col = index % cols;
|
||||||
|
gridPane.add(btn, col, row);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Placeholder for lobby creation logic. Returns a generated lobbyId.
|
||||||
|
*
|
||||||
|
* @return The generated lobbyId
|
||||||
|
*/
|
||||||
|
public int createLobby() {
|
||||||
|
// TODO: Replace with actual lobby creation logic
|
||||||
|
int lobbyId = (int) (Math.random() * 10000 + 1);
|
||||||
|
System.out.println("Lobby created: " + lobbyId);
|
||||||
|
return lobbyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Placeholder for joining a lobby.
|
||||||
|
*
|
||||||
|
* @param lobbyId The lobbyId to join
|
||||||
|
*/
|
||||||
|
public void joinLobby(int lobbyId) {
|
||||||
|
// TODO: Replace with actual join logic
|
||||||
|
System.out.println("Joining lobby: " + lobbyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the GridPane.
|
||||||
|
*
|
||||||
|
* @return The GridPane for the button grid
|
||||||
|
*/
|
||||||
|
public javafx.scene.layout.GridPane getGridPane() {
|
||||||
|
return gridPane;
|
||||||
|
}
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verwaltet das Mapping zwischen Button-IDs und Lobby-IDs rein im Speicher.
|
||||||
|
* Keine Dateioperationen, nur Laufzeitdatenstruktur.
|
||||||
|
*/
|
||||||
|
public class LobbyButtonTranslationManager {
|
||||||
|
/** Maximale Anzahl an Buttons/Lobbys */
|
||||||
|
private static final int MAX_BUTTONS = 8;
|
||||||
|
/** Zuordnung ButtonID → LobbyID */
|
||||||
|
private final Map<Integer, Integer> buttonIdToLobbyId = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konstruktor: initialisiert die Zuordnung leer.
|
||||||
|
*/
|
||||||
|
public LobbyButtonTranslationManager() {
|
||||||
|
// Zuordnung bleibt leer beim Start
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft, ob das Grid voll ist (MAX_BUTTONS erreicht).
|
||||||
|
* @return true, wenn Grid voll; sonst false
|
||||||
|
*/
|
||||||
|
public boolean isFull() {
|
||||||
|
return buttonIdToLobbyId.size() >= MAX_BUTTONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fügt eine Zuordnung ButtonID → LobbyID hinzu.
|
||||||
|
* @param buttonId Die ID des Buttons
|
||||||
|
* @param lobbyId Die ID der Lobby
|
||||||
|
* @throws Exception wenn das Grid voll ist
|
||||||
|
*/
|
||||||
|
public void addLobbyButton(int buttonId, int lobbyId) throws Exception {
|
||||||
|
if (isFull()) throw new Exception("Grid is full!");
|
||||||
|
buttonIdToLobbyId.put(buttonId, lobbyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entfernt eine Zuordnung für die gegebene ButtonID.
|
||||||
|
* @param buttonId Die ID des zu entfernenden Buttons
|
||||||
|
*/
|
||||||
|
public void removeLobbyButton(int buttonId) {
|
||||||
|
buttonIdToLobbyId.remove(buttonId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die LobbyID für eine gegebene ButtonID zurück.
|
||||||
|
* @param buttonId Die ButtonID
|
||||||
|
* @return Die zugehoerige LobbyID oder null, falls nicht vorhanden
|
||||||
|
*/
|
||||||
|
public Integer getLobbyIdForButton(int buttonId) {
|
||||||
|
return buttonIdToLobbyId.get(buttonId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die gesamte Zuordnung ButtonID → LobbyID zurück.
|
||||||
|
* @return Map aller Zuordnungen
|
||||||
|
*/
|
||||||
|
public Map<Integer, Integer> getButtonIdToLobbyId() {
|
||||||
|
return buttonIdToLobbyId;
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
@@ -0,0 +1,160 @@
|
|||||||
|
/* Pixel-Art Font (WICHTIG: Nutze eine Monospace-Schrift für Pixel-Look) */
|
||||||
|
.root {
|
||||||
|
-fx-background-color: #000000;
|
||||||
|
-fx-font-family: "Monospaced", "Courier New";
|
||||||
|
}
|
||||||
|
|
||||||
|
.anchor-pane-bg {
|
||||||
|
-fx-background-color: #ffffff;
|
||||||
|
/* Optional: Bild entfernen oder als Overlay nutzen */
|
||||||
|
-fx-background-image: url("/images/background.png");
|
||||||
|
-fx-background-size: cover;
|
||||||
|
-fx-background-position: center center;
|
||||||
|
-fx-background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DIE SCHWEBENDE INFO-BOX (PIXEL-STYLE) */
|
||||||
|
.floating-chat-box {
|
||||||
|
-fx-background-color: #0d9e3b;
|
||||||
|
/* Pixel-Ränder: Keine Rundung (0px) oder nur sehr kleine Stufen */
|
||||||
|
-fx-background-radius: 58;
|
||||||
|
-fx-border-radius: 50;
|
||||||
|
-fx-border-color: #5c3d10 #3d260a #3d260a #5c3d10;
|
||||||
|
-fx-border-width: 12;
|
||||||
|
-fx-padding: 20;
|
||||||
|
/* Harter Schatten statt weicher Glow */
|
||||||
|
-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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-text {
|
||||||
|
-fx-text-fill: #ffffff;
|
||||||
|
-fx-font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DER OVALE PIXEL-TISCH */
|
||||||
|
.casino-table {
|
||||||
|
-fx-background-color: #0d9e3b; /* Feste Farbe statt Gradient für Pixel-Look */
|
||||||
|
/* Oval durch festen Radius - Pixel-Art-Ovale sind stufig */
|
||||||
|
-fx-background-radius: 2000;
|
||||||
|
-fx-border-radius: 2000;
|
||||||
|
|
||||||
|
/* Dicker, eckiger Holzrand */
|
||||||
|
-fx-border-color: #5c3d10 #3d260a #3d260a #5c3d10;
|
||||||
|
-fx-border-width: 12;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.table-title {
|
||||||
|
-fx-text-fill: #ffffff;
|
||||||
|
-fx-font-size: 28px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-effect: dropshadow(one-pass-box, #000, 0, 0, 3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Hauptcontainer der Statusbox */
|
||||||
|
.player-status-pane {
|
||||||
|
-fx-background-color: rgb(129, 13, 158);
|
||||||
|
-fx-background-radius: 15;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
|
||||||
|
/* -fx-border-color: #5c3d10 #3d260a #3d260a #5c3d10;
|
||||||
|
-fx-border-width: 2;
|
||||||
|
-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 10, 0, 0, 4);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-status-pane:hover {
|
||||||
|
-fx-translate-y: -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Die zwei inneren Boxen */
|
||||||
|
.status-inner-box-top {
|
||||||
|
-fx-background-color: rgb(13, 93, 158);
|
||||||
|
-fx-background-radius: 19;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
-fx-padding: 5 10;
|
||||||
|
-fx-border-color: #5c3d10 #3d260a #3d260a #5c3d10;
|
||||||
|
-fx-border-width: 3;
|
||||||
|
-fx-effect: dropshadow(one-pass-box, rgba(0, 0, 0, 0.8), 0, 0, 3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-inner-box-midle {
|
||||||
|
-fx-background-color: rgba(13, 158, 59, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-inner-box-bottom {
|
||||||
|
-fx-background-color: rgb(158, 13, 102);
|
||||||
|
-fx-background-radius: 19;
|
||||||
|
-fx-border-radius: 15;
|
||||||
|
-fx-padding: 5 10;
|
||||||
|
-fx-border-color: #5c3d10 #3d260a #3d260a #5c3d10;
|
||||||
|
-fx-border-width: 3;
|
||||||
|
-fx-effect: dropshadow(one-pass-box, rgba(0, 0, 0, 0.8), 0, 0, 3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-title {
|
||||||
|
/* Titel-Text anpassen */
|
||||||
|
-fx-text-fill: #ffffff;
|
||||||
|
-fx-font-size: 32px;
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-effect: dropshadow(one-pass-box, #000, 0, 0, 3, 3);
|
||||||
|
-fx-padding: 10 0 0 0; /* Abstand nach oben */
|
||||||
|
}
|
||||||
|
|
||||||
|
.green-box {
|
||||||
|
/* Grüne Box anpassen */
|
||||||
|
-fx-fill: #4CAF50;
|
||||||
|
-fx-stroke: #FFFFFF;
|
||||||
|
-fx-stroke-width: 3;
|
||||||
|
-fx-effect: dropshadow(one-pass-box, #000, 0, 0, 10, 10);
|
||||||
|
-fx-padding: 0 0 40 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EXIT BUTTON */
|
||||||
|
.button-exit {
|
||||||
|
-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;
|
||||||
|
-fx-background-color: #333333;
|
||||||
|
-fx-border-color: #666666;
|
||||||
|
-fx-text-fill: #CCCCCC;
|
||||||
|
}
|
||||||
|
.button-exit:hover {
|
||||||
|
-fx-translate-y: -3;
|
||||||
|
-fx-effect: dropshadow(one-pass-box, rgba(0, 0, 0, 0.8), 0, 0, 3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LOBBY ERSTELLEN BUTTON */
|
||||||
|
.button-create-lobby {
|
||||||
|
-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;
|
||||||
|
-fx-background-color: #1a7f2e;
|
||||||
|
-fx-border-color: #2ecc71;
|
||||||
|
-fx-text-fill: #ffffff;
|
||||||
|
}
|
||||||
|
.button-create-lobby:hover {
|
||||||
|
-fx-translate-y: -3;
|
||||||
|
-fx-effect: dropshadow(one-pass-box, rgba(0, 0, 0, 0.8), 0, 0, 3, 3);
|
||||||
|
-fx-background-color: #27ae60;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
|
||||||
|
<AnchorPane xmlns="http://javafx.com"
|
||||||
|
xmlns:fx="http://javafx.com"
|
||||||
|
fx:controller="ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui.CasinomainuiController"
|
||||||
|
styleClass="anchor-pane-bg"
|
||||||
|
stylesheets="@Casinomainui.css">
|
||||||
|
|
||||||
|
<GridPane prefWidth="1200" prefHeight="800" AnchorPane.topAnchor="0" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0">
|
||||||
|
<columnConstraints>
|
||||||
|
<!-- Tisch bekommt 75% vom Fenster -->
|
||||||
|
<ColumnConstraints percentWidth="70.0" hgrow="ALWAYS" />
|
||||||
|
<!-- Info-Box bekommt 25% vom Fenster inkl. 5 prozent buffer -->
|
||||||
|
<ColumnConstraints percentWidth="5.0" hgrow="ALWAYS" />
|
||||||
|
<ColumnConstraints percentWidth="25.0" hgrow="ALWAYS" />
|
||||||
|
</columnConstraints>
|
||||||
|
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints vgrow="ALWAYS" />
|
||||||
|
</rowConstraints>
|
||||||
|
|
||||||
|
<children>
|
||||||
|
<!-- LINKER BEREICH (Tisch) -->
|
||||||
|
<GridPane GridPane.columnIndex="0" style="-fx-background-color: transparent;" alignment="CENTER">
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints percentHeight="25.0" vgrow="ALWAYS" />
|
||||||
|
<RowConstraints percentHeight="75.0" vgrow="ALWAYS" />
|
||||||
|
</rowConstraints>
|
||||||
|
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="ALWAYS" />
|
||||||
|
</columnConstraints>
|
||||||
|
|
||||||
|
<children>
|
||||||
|
<HBox alignment="CENTER" spacing="20"
|
||||||
|
maxWidth="Infinity"
|
||||||
|
GridPane.rowIndex="0"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
GridPane.halignment="CENTER">
|
||||||
|
<ImageView fx:id="logoView"
|
||||||
|
fitHeight="96"
|
||||||
|
fitWidth="96"
|
||||||
|
preserveRatio="true" />
|
||||||
|
<VBox alignment="CENTER" spacing="5">
|
||||||
|
<Label text="placeholder text wird in controller ueberschriebeen"
|
||||||
|
styleClass="table-title"
|
||||||
|
fx:id="titleLabel"
|
||||||
|
alignment="CENTER" />
|
||||||
|
<Label text="placeholder text wird in controller ueberschriebeen"
|
||||||
|
styleClass="table-title"
|
||||||
|
fx:id="subtitleLabel"
|
||||||
|
alignment="CENTER" />
|
||||||
|
</VBox>
|
||||||
|
</HBox>
|
||||||
|
<Button text="EXIT"
|
||||||
|
styleClass="button-exit"
|
||||||
|
fx:id="exitbutton"
|
||||||
|
onAction="#handleexitbutton"
|
||||||
|
GridPane.rowIndex="0"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
GridPane.halignment="LEFT"
|
||||||
|
GridPane.valignment="TOP">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets top="20" left="20" />
|
||||||
|
</GridPane.margin>
|
||||||
|
</Button>
|
||||||
|
<Button text="Lobby erstellen"
|
||||||
|
styleClass="button-create-lobby"
|
||||||
|
fx:id="createLobbyButton"
|
||||||
|
onAction="#handleCreateLobbyButton"
|
||||||
|
GridPane.rowIndex="0"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
GridPane.halignment="LEFT"
|
||||||
|
GridPane.valignment="TOP">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets top="60" left="20" />
|
||||||
|
</GridPane.margin>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<VBox fx:id="casinoTable"
|
||||||
|
alignment="CENTER"
|
||||||
|
styleClass="casino-table"
|
||||||
|
spacing="20"
|
||||||
|
maxWidth="Infinity"
|
||||||
|
maxHeight="Infinity"
|
||||||
|
GridPane.rowIndex="1"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
GridPane.halignment="CENTER">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets left="20" bottom="20" />
|
||||||
|
</GridPane.margin>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
</GridPane>
|
||||||
|
|
||||||
|
|
||||||
|
<VBox GridPane.columnIndex="1"
|
||||||
|
alignment="CENTER"
|
||||||
|
minWidth="100"
|
||||||
|
minHeight="100">
|
||||||
|
<!-- Bleibt leer -->
|
||||||
|
</VBox>
|
||||||
|
|
||||||
|
<!-- RECHTER BEREICH (Info-Box) -->
|
||||||
|
<VBox GridPane.columnIndex="2" alignment="CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets top="30" right="30" bottom="30" left="10"/>
|
||||||
|
</padding>
|
||||||
|
<VBox VBox.vgrow="ALWAYS" styleClass="floating-chat-box" spacing="10" maxWidth="Infinity">
|
||||||
|
<Label text="== INFO ==" styleClass="chat-header" alignment="CENTER" maxWidth="Infinity"/>
|
||||||
|
<Region minHeight="4" style="-fx-background-color: #ffffff;" />
|
||||||
|
<VBox spacing="15" VBox.vgrow="ALWAYS" styleClass="info-content">
|
||||||
|
<Label text="> CREDITS: 1000" styleClass="info-text"/>
|
||||||
|
<Label text="> JACKPOT: 9999" styleClass="info-text"/>
|
||||||
|
<Label text="> SYSTEM: OK" styleClass="info-text"/>
|
||||||
|
</VBox>
|
||||||
|
</VBox>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
</GridPane>
|
||||||
|
</AnchorPane>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"1": 1240,
|
||||||
|
"2": 3640,
|
||||||
|
"3": 7589,
|
||||||
|
"4": 3982,
|
||||||
|
"5": 5655,
|
||||||
|
"6": 6418,
|
||||||
|
"7": 8586,
|
||||||
|
"8": 7378
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
||||||
|
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class LobbyButtonGridManagerTest {
|
||||||
|
LobbyButtonGridManager gridManager;
|
||||||
|
LobbyButtonTranslationManager translationManager;
|
||||||
|
GridPane gridPane;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
gridPane = new GridPane();
|
||||||
|
translationManager = new LobbyButtonTranslationManager();
|
||||||
|
translationManager.getButtonIdToLobbyId().clear();
|
||||||
|
gridManager = new LobbyButtonGridManager(gridPane, translationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreateLobbyReturnsId() {
|
||||||
|
int lobbyId = gridManager.createLobby();
|
||||||
|
assertTrue(lobbyId > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testJoinLobbyPlaceholder() {
|
||||||
|
// check if exception is thrown
|
||||||
|
assertDoesNotThrow(() -> gridManager.joinLobby(123));
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class LobbyButtonTranslationManagerTest {
|
||||||
|
LobbyButtonTranslationManager manager;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
manager = new LobbyButtonTranslationManager();
|
||||||
|
manager.getButtonIdToLobbyId().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAddLobbyButton() throws Exception {
|
||||||
|
manager.addLobbyButton(1, 100);
|
||||||
|
assertEquals(100, manager.getLobbyIdForButton(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRemoveLobbyButton() throws Exception {
|
||||||
|
manager.addLobbyButton(2, 200);
|
||||||
|
manager.removeLobbyButton(2);
|
||||||
|
assertNull(manager.getLobbyIdForButton(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testIsFull() throws Exception {
|
||||||
|
for (int i = 1; i <= 8; i++) {
|
||||||
|
manager.addLobbyButton(i, 100 + i);
|
||||||
|
}
|
||||||
|
assertTrue(manager.isFull());
|
||||||
|
Exception ex = assertThrows(Exception.class, () -> manager.addLobbyButton(9, 109));
|
||||||
|
assertEquals("Grid is full!", ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetButtonIdToLobbyId() throws Exception {
|
||||||
|
manager.addLobbyButton(4, 400);
|
||||||
|
Map<Integer, Integer> map = manager.getButtonIdToLobbyId();
|
||||||
|
assertTrue(map.containsKey(4));
|
||||||
|
assertEquals(400, map.get(4));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user