hover effect FX

This commit is contained in:
2026-04-14 01:48:23 +02:00
parent 0f83411ab0
commit d475387cec
10 changed files with 377 additions and 29 deletions

View File

@@ -94,8 +94,9 @@ public class DeckGridAppFX extends Application {
} catch ( IOException e) {
throw new RuntimeException(e);
}
//File fileCsv = new File(getClass().getResource("/files/cards.csv").toURI());
game.newGame(csvStream);
// using false for Testing purpose
game.newGame(csvStream, false);
game.setEventListener(notification -> {
Platform.runLater(() -> {
@@ -150,9 +151,6 @@ public class DeckGridAppFX extends Application {
playersArea.setAlignment(Pos.CENTER);
playersArea.setPadding(new Insets(20));
VBox tableArea = new VBox(20,
new Label(" "), topRow,
new Label(" "), centerRow,

View File

@@ -0,0 +1,346 @@
package client;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import server.Era;
import server.Player;
import server.TotemColor;
import server.automaton.Game;
import server.cards.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class DeckViewerEventFX extends Application {
private PDDocument document;
private PDFRenderer pdfRenderer;
private int currentIndex = 0;
private int totalCards = 0;
private ImageView cardImageView;
private Label pageLabel;
private Button btnPrev;
private Button btnNext;
@Override
public void start(Stage primaryStage) {
List<Player> players = new ArrayList<>();
players.add(new Player("Yoshi", TotemColor.YELLOW));
players.add(new Player("Pippo", TotemColor.PURPLE));
players.add(new Player("John", TotemColor.RED));
players.add(new Player("Baggio", TotemColor.BLUE));
players.add(new Player("Gino", TotemColor.GREEN));
Game game = new Game(players);
InputStream csvStream = getClass().getResourceAsStream("/files/cards.csv");
game.newGame(csvStream, false);
primaryStage.setTitle("Visualizzatore Mazzo di Carte (PDF)");
// Componente per mostrare la carta
cardImageView = new ImageView();
cardImageView.setFitHeight(500); // Altezza fissa, larghezza in proporzione
cardImageView.setPreserveRatio(true);
cardImageView.setStyle("-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.5), 10, 0, 0, 0);");
// Controlli UI
btnPrev = new Button("⬅ Carta Precedente");
btnNext = new Button("Carta Successiva ➡");
pageLabel = new Label("Nessun mazzo caricato");
Button btnLoad = new Button("Carica PDF Mazzo");
Button btnGrid = new Button("Grid View");
Button btnGridEv = new Button("Grid Event");
Button btnGridBu = new Button("Grid Building");
// Azioni dei pulsanti
btnLoad.setOnAction(e -> loadPdf(primaryStage));
btnPrev.setOnAction(e -> showCard(currentIndex - 1));
btnNext.setOnAction(e -> showCard(currentIndex + 1));
btnGrid.setOnAction(e -> showAllCardsGrouped(game));
btnGridEv.setOnAction(e -> showEventCardsGrouped(game));
btnGridBu.setOnAction(e -> showBuildingCardsGrouped(game));
updateButtons();
//showAllCardsGrouped(Game game)
// Layout
HBox controls = new HBox(15, btnGridEv, btnGridBu, btnGrid, btnPrev, pageLabel, btnNext);
controls.setAlignment(Pos.CENTER);
VBox topBox = new VBox(10, btnLoad);
topBox.setAlignment(Pos.CENTER);
topBox.setPadding(new Insets(10));
BorderPane root = new BorderPane();
root.setTop(topBox);
root.setCenter(cardImageView);
root.setBottom(controls);
BorderPane.setMargin(cardImageView, new Insets(20));
BorderPane.setMargin(controls, new Insets(20));
Scene scene = new Scene(root, 600, 700);
primaryStage.setScene(scene);
primaryStage.show();
}
private void loadPdf(Stage stage) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Seleziona il PDF del mazzo di carte");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("File PDF", "*.pdf"));
File file = fileChooser.showOpenDialog(stage);
if (file != null) {
try {
// Chiude il documento precedente se esiste
if (document != null) {
document.close();
}
// Carica il nuovo PDF
document = PDDocument.load(file);
pdfRenderer = new PDFRenderer(document);
totalCards = document.getNumberOfPages();
// Mostra la prima carta
showCard(0);
} catch (IOException e) {
e.printStackTrace();
pageLabel.setText("Errore nel caricamento del file!");
}
}
}
private void showCard(int index) {
if (document == null || index < 0 || index >= totalCards) return;
try {
// Renderizza la pagina del PDF in un'immagine BufferedImage (DPI 150 per buona qualità)
BufferedImage bim = pdfRenderer.renderImageWithDPI(index, 150);
// Converte l'immagine di AWT (Swing) in un'immagine JavaFX
Image fxImage = SwingFXUtils.toFXImage(bim, null);
cardImageView.setImage(fxImage);
currentIndex = index;
pageLabel.setText("Carta " + (currentIndex + 1) + " di " + totalCards);
updateButtons();
} catch (IOException e) {
e.printStackTrace();
}
}
private ImageView loadCardImage(int index, int height) {
if (document == null || index < 0 || index >= totalCards) return null;
try {
BufferedImage bim = pdfRenderer.renderImageWithDPI(index, 150);
Image fxImage = SwingFXUtils.toFXImage(bim, null);
ImageView imageView = new ImageView(fxImage);
imageView.setPreserveRatio(true);
imageView.setFitHeight(height);
return imageView;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private void updateButtons() {
btnPrev.setDisable(document == null || currentIndex == 0);
btnNext.setDisable(document == null || currentIndex == totalCards - 1);
}
@Override
public void stop() throws Exception {
// Importante: chiudere il documento per liberare la memoria quando l'app si chiude
if (document != null) {
document.close();
}
super.stop();
}
private void showAllCardsGrouped(Game game) {
if (document == null || pdfRenderer == null) return;
VBox rootBox = new VBox(30);
rootBox.setPadding(new Insets(20));
// Group cards by type
//Card ctop = gameBoard.getTopRow().stream().filter(s -> s instanceof CharacterCard
Map<CharacterType, List<CharacterCard>> cardsByType =
game.getGameBoard()
.getCardDeck()
.getTribeDeck()
.stream()
.filter(s -> s instanceof CharacterCard)
.map(s -> (CharacterCard) s)
.collect(Collectors.groupingBy(CharacterCard::getCharacterType));
for (Map.Entry<CharacterType, List<CharacterCard>> entry : cardsByType.entrySet()) {
CharacterType type = entry.getKey();
List<CharacterCard> cards = entry.getValue();
// Title for the group
Label typeLabel = new Label("Tipo: " + type);
typeLabel.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;");
// Grid for cards (4 columns = 4 cards per row)
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
for (int i = 0; i < cards.size(); i++) {
Card card = cards.get(i);
int col = i % 4;
int row = i / 4;
ImageView imageView = loadCardImage(card.getCardId(), 200);
grid.add(imageView, col, row);
}
rootBox.getChildren().addAll(typeLabel, grid);
}
ScrollPane scrollPane = new ScrollPane(rootBox);
scrollPane.setFitToWidth(true);
Stage stage = new Stage();
stage.setTitle("Tutte le carte per tipo");
stage.setScene(new Scene(scrollPane, 1200, 900));
stage.show();
}
private void showEventCardsGrouped(Game game) {
if (document == null || pdfRenderer == null) return;
VBox rootBox = new VBox(30);
rootBox.setPadding(new Insets(20));
// Group cards by type
//Card ctop = gameBoard.getTopRow().stream().filter(s -> s instanceof CharacterCard
Map<Event, List<EventCard>> cardsByType =
game.getGameBoard()
.getCardDeck()
.getTribeDeck()
.stream()
.filter(s -> s instanceof EventCard)
.map(s -> (EventCard) s)
.collect(Collectors.groupingBy(EventCard::getEvent));
for (Map.Entry<Event, List<EventCard>> entry : cardsByType.entrySet()) {
Event type = entry.getKey();
List<EventCard> cards = entry.getValue();
// Title for the group
Label typeLabel = new Label("Tipo: " + type);
typeLabel.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;");
// Grid for cards (4 columns = 4 cards per row)
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
for (int i = 0; i < cards.size(); i++) {
Card card = cards.get(i);
int col = i % 4;
int row = i / 4;
ImageView imageView = loadCardImage(card.getCardId(), 200);
grid.add(imageView, col, row);
}
rootBox.getChildren().addAll(typeLabel, grid);
}
ScrollPane scrollPane = new ScrollPane(rootBox);
scrollPane.setFitToWidth(true);
Stage stage = new Stage();
stage.setTitle("Tutte le carte per tipo");
stage.setScene(new Scene(scrollPane, 1200, 900));
stage.show();
}
private void showBuildingCardsGrouped(Game game) {
if (document == null || pdfRenderer == null) return;
VBox rootBox = new VBox(30);
rootBox.setPadding(new Insets(20));
Map<server.Era, List<Card>> cardsByType =game.getGameBoard().getCardDeck().getBuildingDeckMap();
for (Map.Entry<server.Era, List<Card>> entry : cardsByType.entrySet()) {
server.Era type = entry.getKey();
List<Card> cards = entry.getValue();
// Title for the group
Label typeLabel = new Label("Tipo: " + type);
typeLabel.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;");
// Grid for cards (4 columns = 4 cards per row)
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
for (int i = 0; i < cards.size(); i++) {
Card card = cards.get(i);
int col = i % 4;
int row = i / 4;
ImageView imageView = loadCardImage(card.getCardId(), 200);
grid.add(imageView, col, row);
}
rootBox.getChildren().addAll(typeLabel, grid);
}
ScrollPane scrollPane = new ScrollPane(rootBox);
scrollPane.setFitToWidth(true);
Stage stage = new Stage();
stage.setTitle("Tutte le carte per tipo");
stage.setScene(new Scene(scrollPane, 1200, 900));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

View File

@@ -51,7 +51,7 @@ public class DeckViewerFX extends Application {
Game game = new Game(players);
InputStream csvStream = getClass().getResourceAsStream("/files/cards.csv");
game.newGame(csvStream);
game.newGame(csvStream, false);
primaryStage.setTitle("Visualizzatore Mazzo di Carte (PDF)");

View File

@@ -97,12 +97,12 @@ public class Game {
* Initial food (rulebook setup step 10):
* Slot 1 -> 2 food, slots 2-3 -> 3 food, slots 4-5 -> 4 food.
*/
public void newGame(InputStream csvStream) {
public void newGame(InputStream csvStream, boolean shuffle) {
try {
logger.info(" ---- STARTING NEW GAME ----- ");
CardDeck deck = new CardDeck();
deck.setForNPlayer(csvStream, players.size());
deck.setForNPlayer(csvStream, players.size(), shuffle);
gameBoard = new GameBoard(Era.I, deck, players.size());
gameBoard.initOfferingTiles(players.size());
@@ -617,11 +617,11 @@ public class Game {
}
private void resolveOneEvent(EventCard event) {
logger.info(">>"+gameBoard.getTurnTile());
logger.info(">> before event "+gameBoard.getTurnTile());
notify( GameState.EVENT_RESOLUTION, event.toString());
logger.info("SOLVE EVENT: " + event.getEvent() +" - " +event.getCardId() +" (Era " + event.getEra() + ")");
EventsSolver.solveEvents(Collections.singletonList(event), players);
logger.info("<<"+gameBoard.getTurnTile());
logger.info("<< after event "+gameBoard.getTurnTile());
}
private void startNewRound() {

View File

@@ -27,6 +27,10 @@ public class CardDeck {
return buildingDeck.get(era);
}
public Map<Era, List<Card>> getBuildingDeckMap() {
return buildingDeck;
}
public void setForNPlayerPathTest(String path, int n) throws LoadingCardsException {
List<Card> tribe = new ArrayList<>();
@@ -74,7 +78,7 @@ public class CardDeck {
public void setForNPlayer(InputStream csvStream, int n) throws LoadingCardsException {
public void setForNPlayer(InputStream csvStream, int n, boolean shuffle) throws LoadingCardsException {
List<Card> tribe = new ArrayList<>();
List<Card> building = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(csvStream))) {
@@ -106,13 +110,13 @@ public class CardDeck {
throw new LoadingCardsException("file not found");
}
building = CardDeck.shuffle(building);
if (shuffle) building = CardDeck.shuffle(building);
this.tribeDeck = tribe.stream()
.filter(card -> card.getForMinPlayer() <= n)
.collect(Collectors.toCollection(ArrayList::new));
this.tribeDeck = CardDeck.shuffle(this.tribeDeck);
if (shuffle) this.tribeDeck = CardDeck.shuffle(this.tribeDeck);
this.buildingDeck = building.stream().collect(Collectors.groupingBy(Card::getEra));
}