Fix: Resolving Git Merge Conflicts #253

Merged
j.kropff merged 69 commits from chore/ui-checkstyle-fixes into main 2026-04-11 15:10:58 +02:00
Showing only changes of commit 76e62b3cff - Show all commits
@@ -38,15 +38,9 @@ public class LobbyButtonGridManager {
/** Manager for mapping ButtonID to LobbyID. */
private final LobbyButtonTranslationManager translationManager;
/** Number of rows in the grid. */
private static final int ROWS = 2;
/** Number of columns in the grid. */
private static final int COLS = 4;
/** Path to the button image. */
private static final String BUTTON_IMAGE_PATH = "/images/logo.png";
/** Image for a lobby in CREATED state. */
/** Default fallback image. */
private static final String BUTTON_FALLBACK_IMAGE = "/images/lobbypictures/error.png";
@@ -61,25 +55,17 @@ public class LobbyButtonGridManager {
/** Cache for loaded Images keyed by resource path. */
private final ConcurrentHashMap<String, Image> imageCache = new ConcurrentHashMap<>();
/** Max random lobby id. */
private static final int MAX_RANDOM_LOBBY_ID = 10000;
private final LobbyClient lobbyClient;
/** Executor for background status/network tasks. */
private final ExecutorService executor = Executors.newCachedThreadPool();
/**
* 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, translationManager, createDefaultLobbyClient());
}
/**
* Constructor that accepts a `LobbyClient` implementation.
*/
public LobbyButtonGridManager(
GridPane gridPane, LobbyButtonTranslationManager translationManager, LobbyClient lobbyClient) {
this.gridPane = gridPane;
@@ -88,17 +74,20 @@ public class LobbyButtonGridManager {
this.lobbyClient = lobbyClient;
}
private static LobbyClient createDefaultLobbyClient() {
String host = System.getProperty("casono.server.host", "127.0.0.1");
int port = 1337;
try {
port = Integer.parseInt(System.getProperty("casono.server.port", "1337"));
} catch (NumberFormatException e) {
// use default port if parsing fails
}
return new LobbyClient(new ClientService(host, port));
/**
* Convenience constructor: accept a {@link ClientService} and build a
* {@link LobbyClient} from it. This avoids any host/port System.getProperty
* lookups elsewhere — caller controls the ClientService.
*/
public LobbyButtonGridManager(
GridPane gridPane, LobbyButtonTranslationManager translationManager, ClientService clientService) {
this(gridPane, translationManager, new LobbyClient(clientService));
}
// Default client creation removed to avoid implicit IP/port configuration.
// Applications must construct and provide a LobbyClient or ClientService
// explicitly.
/**
* Renders all lobby buttons in the grid. Creates a button for each mapping with
* image and event
@@ -106,10 +95,8 @@ public class LobbyButtonGridManager {
*/
public void renderLobbyButtons() {
gridPane.getChildren().clear();
int index = 0;
Map<Integer, Integer> mapping = translationManager.getButtonIdToLobbyId();
if (mapping.isEmpty()) {
// No buttons to render
return;
}
List<Integer> buttonIds = new ArrayList<>(mapping.keySet());
@@ -140,21 +127,6 @@ if (targetLobbyId != null) {
}
});
// async fetch status and update image
});
// async fetch status and update image
CompletableFuture.supplyAsync(() -> lobbyClient.fetchLobbyStatusString(lobbyId), executor)
.thenAccept(statusStr -> {
LobbyStatus status = parseLobbyStatus(statusStr);
String path = getImagePathForButton(buttonId, status == null ? LobbyStatus.CREATED : status);
Image img = safeLoadImage(path);
javafx.application.Platform.runLater(() -> {
ImageView iv = new ImageView(img);
iv.setPreserveRatio(true);
iv.fitWidthProperty()
.bind(gridPane.widthProperty().divide(COLS).subtract(BUTTON_WIDTH_MARGIN));
iv.setSmooth(true);
btn.setGraphic(iv);
});
CompletableFuture.supplyAsync(() -> lobbyClient.fetchLobbyStatusString(lobbyId), executor)
.thenAccept(statusStr -> {
LobbyStatus status = parseLobbyStatus(statusStr);
@@ -214,12 +186,6 @@ if (targetLobbyId != null) {
}
}
private String getImagePathForStatus(LobbyStatus status) {
return status == LobbyStatus.CREATED
? String.format(BUTTON_IMAGE_TEMPLATE, 0, "created")
: String.format(BUTTON_IMAGE_TEMPLATE, 0, "running");
}
private String getImagePathForButton(int buttonId, LobbyStatus status) {
String statusStr = status == LobbyStatus.CREATED ? "created" : "running";
return String.format(BUTTON_IMAGE_TEMPLATE, buttonId, statusStr);
@@ -265,9 +231,6 @@ if (targetLobbyId != null) {
/** Update all lobby buttons' images according to the current lobby statuses. */
public void updateLobbyButtonImages() {
// Run on FX thread to be safe
javafx.application.Platform.runLater(
() -> {
Map<Integer, Integer> mapping = translationManager.getButtonIdToLobbyId();
if (mapping.isEmpty()) {
return;
@@ -298,7 +261,6 @@ javafx.application.Platform.runLater(() -> {
});
});
}
});
}
/**
@@ -310,13 +272,13 @@ javafx.application.Platform.runLater(() -> {
try {
int lobbyId = lobbyClient.createLobby();
LOGGER.info("Lobby created via LobbyClient: {}", lobbyId);
if (lobbyId <= 0) {
throw new RuntimeException("LobbyClient returned invalid lobby id: " + lobbyId);
}
return lobbyId;
} catch (Exception e) {
LOGGER.error("Failed to create lobby via LobbyClient: {}", e.getMessage());
// Fallback: generate a local id so UI can continue to work in offline mode
int lobbyId = (int) (Math.random() * MAX_RANDOM_LOBBY_ID + 1);
LOGGER.warn("Falling back to local generated lobby id: {}", lobbyId);
return lobbyId;
throw new RuntimeException("Failed to create lobby", e);
}
}
@@ -374,4 +336,12 @@ javafx.application.Platform.runLater(() -> {
return gridPane;
}
/**
* Expose the configured LobbyClient so callers can invoke its methods
* directly (createLobby, fetchLobbyStatusString, joinLobby, ...).
*/
public LobbyClient getLobbyClient() {
return lobbyClient;
}
}