Files
mesos2/src/main/java/org/example/mesosll07/DeckGridApp.java

208 lines
7.1 KiB
Java

package org.example.mesosll07;
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.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DeckGridApp extends Application {
// Inizializza il Logger
private static final Logger logger = LogManager.getLogger(DeckGridApp.class);
private PDDocument document;
private PDFRenderer pdfRenderer;
private int totalCards = 0;
// Contenitori per le tre righe
private HBox topRow;
private HBox centerRow;
private HBox bottomRow;
private Button btnShuffle;
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Tavolo da Gioco - Carte Casuali");
logger.info("Avvio dell'applicazione JavaFX");
// Pulsanti
Button btnLoad = new Button("Carica PDF Mazzo");
btnShuffle = new Button("Rimescola Carte");
btnShuffle.setDisable(true); // Disabilitato finché non si carica un PDF
btnLoad.setOnAction(e -> loadPdf(primaryStage));
btnShuffle.setOnAction(e -> distributeRandomCards());
HBox topMenu = new HBox(15, btnLoad, btnShuffle);
topMenu.setAlignment(Pos.CENTER);
topMenu.setPadding(new Insets(10));
// Setup delle tre righe (spazio tra le carte impostato a 10px)
topRow = createRowContainer();
centerRow = createRowContainer();
bottomRow = createRowContainer();
// Contenitore verticale per le righe
VBox tableArea = new VBox(30,
new Label("TOP (8 Carte):"), topRow,
new Label("CENTER (6 Carte):"), centerRow,
new Label("BOTTOM (7 Carte):"), bottomRow
);
tableArea.setAlignment(Pos.CENTER);
tableArea.setPadding(new Insets(20));
// Mettiamo il tavolo in uno ScrollPane nel caso le carte siano troppo grandi per lo schermo
ScrollPane scrollPane = new ScrollPane(tableArea);
scrollPane.setFitToWidth(true);
BorderPane root = new BorderPane();
root.setTop(topMenu);
root.setCenter(scrollPane);
// Finestra un po' più grande per contenere tutte queste carte
Scene scene = new Scene(root, 1200, 800);
primaryStage.setScene(scene);
primaryStage.show();
}
private HBox createRowContainer() {
HBox row = new HBox(15); // 15px di spazio tra una carta e l'altra
row.setAlignment(Pos.CENTER);
return row;
}
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 {
if (document != null) {
document.close();
}
logger.info("Caricamento file PDF: {}", file.getAbsolutePath());
document = PDDocument.load(file);
pdfRenderer = new PDFRenderer(document);
totalCards = document.getNumberOfPages();
logger.info("PDF caricato. Pagine totali (carte): {}", totalCards);
btnShuffle.setDisable(false);
// Distribuisci le carte per la prima volta
distributeRandomCards();
} catch (IOException e) {
logger.error("Errore nel caricamento del PDF", e);
}
}
}
private void distributeRandomCards() {
if (document == null || totalCards == 0) return;
logger.info("Inizio rimescolamento e distribuzione carte...");
// Pulisce il tavolo dalle carte precedenti
topRow.getChildren().clear();
centerRow.getChildren().clear();
bottomRow.getChildren().clear();
// 1. Crea una lista con tutti gli indici (da 0 al numero totale di pagine)
List<Integer> deckIndices = new ArrayList<>();
for (int i = 0; i < totalCards; i++) {
deckIndices.add(i);
}
// 2. Mescola la lista (Simula la mescolata del mazzo)
Collections.shuffle(deckIndices);
// 3. Distribuisci nelle righe (evitando IndexOutOfBounds se il PDF ha meno di 21 pagine)
// Riga Top: 8 carte
populateRow(topRow, deckIndices, 0, 8);
// Riga Center: 6 carte
populateRow(centerRow, deckIndices, 8, 6);
// Riga Bottom: 7 carte
populateRow(bottomRow, deckIndices, 14, 7);
logger.info("Distribuzione completata.");
}
private void populateRow(HBox row, List<Integer> deckIndices, int startIndex, int numberOfCards) {
for (int i = 0; i < numberOfCards; i++) {
int actualIndex = startIndex + i;
// Se abbiamo esaurito le carte nel PDF, interrompiamo
if (actualIndex >= deckIndices.size()) {
logger.warn("Il PDF non ha abbastanza carte per riempire questa riga.");
break;
}
int pageNumber = deckIndices.get(actualIndex);
ImageView cardImage = createCardImageView(pageNumber);
if (cardImage != null) {
row.getChildren().add(cardImage);
}
}
}
private ImageView createCardImageView(int pageIndex) {
try {
// Renderizza la pagina. Usiamo 100 DPI invece di 150 per risparmiare RAM,
// dato che ora stiamo generando 21 immagini contemporaneamente.
BufferedImage bim = pdfRenderer.renderImageWithDPI(pageIndex, 100);
Image fxImage = SwingFXUtils.toFXImage(bim, null);
ImageView imageView = new ImageView(fxImage);
// Impostiamo l'altezza fissa per le carte, in modo che stiano sullo schermo
imageView.setFitHeight(180);
imageView.setPreserveRatio(true);
imageView.setStyle("-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.5), 5, 0, 0, 0);");
return imageView;
} catch (IOException e) {
logger.error("Errore durante il rendering della pagina {}", pageIndex, e);
return null;
}
}
@Override
public void stop() throws Exception {
if (document != null) {
document.close();
logger.info("Documento PDF chiuso correttamente.");
}
logger.info("Applicazione terminata.");
super.stop();
}
public static void main(String[] args) {
launch(args);
}
}