Merge branch 'main' into 'feat/game-ui'

This commit is contained in:
jk
2026-03-14 14:02:13 +01:00
40 changed files with 1439 additions and 165 deletions
@@ -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.server.ServerApp;
/**
* Main entry point for Casono application.
* Handles client and server startup.
* <p>
* Standardkonstruktor für die Anwendung.
*/
public final class Main {
/**
* Standardkonstruktor.
*/
public Main() {
// Standardkonstruktor
}
/**
* Main entry point for Casono.
* @param args Command line arguments
*/
public static void main(String[] args) {
if (!isValid(args)) {
printUsage();
@@ -1,6 +1,29 @@
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 {
/**
* 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) {
String[] parts = arg.split(":", 2);
if (parts.length != 2) {
@@ -1,22 +1,26 @@
package ch.unibas.dmi.dbis.cs108.casono.client.ui;
import ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.CasinoGameUI;
import javafx.application.Application;
/**
* Launcher-Klasse für die Casino-Anwendung.
*
* Startet die JavaFX-Anwendung. Während der Entwicklung kann hier direkt
* `Casinogameui` für Tests aufgerufen werden. Im fertigen Spiel erfolgt
* der Aufruf von `Casinogameui` über die `Casinomainui`.
*
* Starte den Client über das Terminal mit:
* {@code ./gradlew run --args="client 0.0.0.0:1234"}
* 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);
Application.launch(CasinoGameUI.class, args);
Application.launch(ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui.Casinomainui.class, args);
}
}
@@ -1,5 +1,9 @@
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;
@@ -7,8 +11,25 @@ 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);
@@ -20,6 +41,10 @@ public class Casinomainui extends Application {
stage.show();
}
/**
* Main entry point for launching the application.
* @param args Command line arguments
*/
public static void main(String[] args) {
launch();
}
@@ -1,22 +1,21 @@
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.layout.AnchorPane;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.scene.shape.Rectangle;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.AnchorPane;
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
@@ -24,26 +23,63 @@ public class CasinomainuiController {
@FXML
private Label subtitleLabel;
@FXML
private javafx.scene.image.ImageView logoView;
private ImageView logoView;
@FXML
private javafx.scene.shape.Rectangle greenBox;
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");
// Logo laden
logoView.setImage(new javafx.scene.image.Image(getClass().getResource("/images/logo.png").toExternalForm()));
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());
}
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -1,8 +1,22 @@
package ch.unibas.dmi.dbis.cs108.casono.server;
import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager;
import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent;
import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus;
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager;
/**
* Application class for starting the server.
*/
public class ServerApp {
public static void start(String arg) {
int port = Integer.parseInt(arg);
System.out.println("You've selected the server. It will accept connections at port " + port);
EventBus eventBus = new EventBus();
SessionManager sessionManager = new SessionManager();
eventBus.subscribe(DisconnectEvent.class, event -> sessionManager.removeSession(event.sessionId()));
NetworkManager networkManager = new NetworkManager(port, sessionManager, eventBus);
networkManager.start();
}
}
@@ -0,0 +1,81 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent;
import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus;
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.Session;
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager;
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TcpTransport;
/**
* Creates and manages the server socket. Accepts new incoming connections and creates sessions.
*/
public class NetworkManager implements Runnable {
private Integer port;
private Logger logger;
private Thread thread;
private Boolean running;
private SessionManager sessionManager;
private EventBus eventBus;
/**
* Creates a new NetworkManager with the given port, session manager, and event bus.
*
* @param port the port to listen on
* @param sessionManager the session manager to use
* @param eventBus the event bus for events
*/
public NetworkManager(Integer port, SessionManager sessionManager, EventBus eventBus) {
this.port = port;
this.logger = LogManager.getLogger(NetworkManager.class);
this.thread = new Thread(this, "networkManager");
this.running = true;
this.sessionManager = sessionManager;
this.eventBus = eventBus;
this.eventBus.subscribe(DisconnectEvent.class, event -> clientDisconnected(event));
}
/**
* Starts the internal thread to accept new connections.
*/
public void start() {
logger.debug("Starting server at port " + port);
thread.start();
}
/**
* Handles client disconnection events.
*
* @param event the disconnect event
*/
public void clientDisconnected(DisconnectEvent event) {
logger.info("Session " + event.sessionId().value() + " disconnected adhasghd");
}
/**
* Runs the network manager loop, accepting connections.
*/
@Override
public void run() {
try (ServerSocket serverSocket = new ServerSocket(port)) {
while (running) {
Socket clientSocket = serverSocket.accept();
System.out.println("Accepted connection from " + clientSocket.getRemoteSocketAddress());
Session session = new Session(new TcpTransport(clientSocket), eventBus);
sessionManager.addSession(session);
session.start();
}
} catch (IOException e) {
logger.fatal(e);
}
}
}
@@ -0,0 +1,8 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network.events;
import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId;
/**
* Represents a disconnect event for a session.
*/
public record DisconnectEvent(SessionId sessionId) implements Event {}
@@ -0,0 +1,6 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network.events;
/**
* Marker interface for events in the event bus system.
*/
interface Event {}
@@ -0,0 +1,40 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network.events;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
/**
* A simple event bus for publishing and subscribing to events.
*/
public class EventBus {
private final Map<Class<?>, List<Consumer<Object>>> handlers = new ConcurrentHashMap<>();
/**
* Subscribes a handler to a specific event type.
*
* @param eventType the class of the event to subscribe to
* @param handler the consumer to handle the event
*/
@SuppressWarnings("unchecked") // This cast is safe, because handlers only get passed the type they subscribed to
public <T extends Event> void subscribe(Class<T> eventType, Consumer<T> handler) {
handlers.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>())
.add((Consumer<Object>) (Consumer<?>) handler);
}
/**
* Publishes an event to all subscribed handlers.
*
* @param event the event to publish
*/
public <T extends Event> void publish(T event) {
Objects.requireNonNull(event, "event must not be null");
List<Consumer<Object>> subscribers = handlers.get(event.getClass());
if (subscribers != null) {
subscribers.forEach(h -> h.accept(event));
}
}
}
@@ -0,0 +1,85 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions;
import java.io.EOFException;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent;
import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus;
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer;
/**
* Represents a client session in the network server.
*/
public class Session implements Runnable {
private SessionId id;
private Thread thread;
private TransportLayer transport;
private Logger logger;
private Boolean running;
private EventBus eventBus;
/**
* Creates a new Session with the given transport and event bus.
*
* @param transport the transport layer for communication
* @param eventBus the event bus for publishing events
* @throws IOException if an I/O error occurs during initialization
*/
public Session(TransportLayer transport, EventBus eventBus) throws IOException {
this.id = new SessionId();
this.thread = new Thread(this, "session-" + this.id.value());
this.transport = transport;
this.running = true;
this.eventBus = eventBus;
this.logger = LogManager.getLogger(Session.class.toString() + id.value());
this.logger.info("Created new session");
}
/**
* Returns the ID of this session.
*
* @return the session ID
*/
public SessionId getId() {
return this.id;
}
/**
* Starts the session thread.
*/
public void start() {
thread.start();
}
/**
* Closes the session and its transport.
*
* @throws IOException if an I/O error occurs
*/
public void close() throws IOException {
transport.close();
this.running = false;
}
/**
* Runs the session loop, reading from the transport.
*/
@Override
public void run() {
while (running) {
try {
System.out.println("Recieved: " + transport.read());
} catch (EOFException e) {
logger.info("Client disconnected");
eventBus.publish(new DisconnectEvent(id));
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
@@ -0,0 +1,35 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions;
import java.util.UUID;
/**
* Represents a unique identifier for a session.
*/
public class SessionId {
private final UUID value;
/**
* Creates a new SessionId with a randomly generated UUID.
*/
public SessionId() {
this.value = UUID.randomUUID();
}
/**
* Creates a new SessionId with the specified UUID.
*
* @param UUID to use for this SessionId
*/
public SessionId(UUID value) {
this.value = value;
}
/**
* Returns the UUID value of this SessionId.
*
* @return the UUID value
*/
public UUID value() {
return value;
}
}
@@ -0,0 +1,59 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Manages active sessions in the server.
*/
public class SessionManager {
private Map<SessionId, Session> sessions;
/**
* Constructs a new SessionManager.
*/
public SessionManager() {
this.sessions = new ConcurrentHashMap<>();
}
/**
* Adds a session to the manager.
*
* @param session the session to add
*/
public void addSession(Session session) {
sessions.put(session.getId(), session);
System.out.println("Added session " + session.getId().value() + " to session manager");
}
/**
* Removes a session by its ID.
*
* @param id the ID of the session to remove
* @return the removed session, or null if not found
*/
public Session removeSession(SessionId id) {
System.out.println("Removed session " + id.value() + " from session manager");
return sessions.remove(id);
}
/**
* Removes the specified session.
*
* @param session the session to remove
* @return the removed session, or null if not found
*/
public Session removeSession(Session session) {
return sessions.remove(session.getId());
}
/**
* Retrieves a session by its ID.
*
* @param id the ID of the session to retrieve
* @return the session with the specified ID, or null if not found
*/
public Session getSessionById(SessionId id) {
return sessions.get(id);
}
}
@@ -0,0 +1,63 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network.transport;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
/**
* Implements TCP-based transport layer for network communication.
*/
public class TcpTransport implements TransportLayer {
private Socket socket;
private DataInputStream in;
private DataOutputStream out;
/**
* Creates a new TcpTransport with the given socket.
*
* @param socket the socket to use for communication
* @throws IOException if an I/O error occurs
*/
public TcpTransport(Socket socket) throws IOException {
this.socket = socket;
this.in = new DataInputStream(socket.getInputStream());
this.out = new DataOutputStream(socket.getOutputStream());
}
/**
* Reads a string from the socket.
*
* @return the read string
* @throws IOException if an I/O error occurs
*/
public String read() throws IOException {
int length = in.readInt();
byte[] payload = new byte[length];
in.readFully(payload);
return new String(payload, StandardCharsets.UTF_8);
}
/**
* Writes a string to the socket.
*
* @param payload the string to write
* @throws IOException if an I/O error occurs
*/
public void write(String payload) throws IOException {
byte[] rawPayload = payload.getBytes(StandardCharsets.UTF_8);
out.writeInt(rawPayload.length);
out.write(rawPayload);
out.flush();
}
/**
* Closes the socket.
*
* @throws IOException if an I/O error occurs
*/
public void close() throws IOException {
socket.close();
}
}
@@ -0,0 +1,31 @@
package ch.unibas.dmi.dbis.cs108.casono.server.network.transport;
import java.io.IOException;
/**
* Interface for transport layer implementations.
*/
public interface TransportLayer {
/**
* Reads data from the transport layer.
*
* @return the read data as a string
* @throws IOException if an I/O error occurs
*/
String read() throws IOException;
/**
* Writes data to the transport layer.
*
* @param data the data to write
* @throws IOException if an I/O error occurs
*/
void write(String data) throws IOException;
/**
* Closes the transport layer.
*
* @throws IOException if an I/O error occurs
*/
void close() throws IOException;
}
@@ -1,12 +0,0 @@
package ch.unibas.dmi.dbis.cs108.example;
/**
* A simple HelloWorld class.
*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
@@ -1,32 +0,0 @@
package ch.unibas.dmi.dbis.cs108.example.gui.javafx;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* This is an example JavaFX-Application.
*/
public class GUI extends Application {
/**
* Launching this method will not work on some platforms.
* What you should do is to create a separate main class and launch the GUI class from there as is done in {@link Main}
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
String javaVersion = System.getProperty("java.version");
String javafxVersion = System.getProperty("javafx.version");
Label l = new Label("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + ".");
Scene scene = new Scene(new StackPane(l), 640, 480);
stage.setScene(scene);
stage.show();
}
}
@@ -1,14 +0,0 @@
package ch.unibas.dmi.dbis.cs108.example.gui.javafx;
import javafx.application.Application;
public class Main {
/**
* This is simply a wrapper to launch the {@link GUI} class.
* The reason this class exists is documented in {@link GUI#main(String[])}
*/
public static void main(String[] args) {
Application.launch(GUI.class, args);
}
}
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout disableAnsi="false" pattern=
"%style{%d{HH:mm:ss.SSS}}{bright,black} %highlight{%-8level}{
FATAL=bright red,
ERROR=red,
WARN=yellow,
INFO=blue,
DEBUG=cyan,
TRACE=white
} %style{%-20logger{20}}{magenta} %msg%n"
/>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
@@ -120,6 +120,7 @@
-fx-padding: 0 0 40 0;
}
/* EXIT BUTTON */
.button-exit {
-fx-background-radius: 12;
-fx-border-radius: 12;
@@ -128,17 +129,17 @@
-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);
}
.button-exit {
-fx-background-color: #333333;
-fx-border-color: #666666;
-fx-text-fill: #CCCCCC;
/* LOBBY ERSTELLEN BUTTON */
.button-create-lobby {
-fx-background-radius: 12;
-fx-border-radius: 12;
-fx-font-family: "Courier New";
@@ -146,6 +147,14 @@
-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;
}
@@ -68,6 +68,18 @@
<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"
@@ -0,0 +1,10 @@
{
"1": 1240,
"2": 3640,
"3": 7589,
"4": 3982,
"5": 5655,
"6": 6418,
"7": 8586,
"8": 7378
}