From 12a0bde35a8e8b21f234442ea8f88b34cc6a04ae Mon Sep 17 00:00:00 2001 From: Kyle-gi Date: Tue, 14 Apr 2026 13:18:10 +0200 Subject: [PATCH 01/29] git commit -m "feat: implementar pantalla principal con jugadores conectados y emparejamiento aleatorio (E3-US3-T6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Añadido MainScreen.fxml con lista de jugadores y botones - Creado MainScreenController con lógica mock para jugadores y desafíos - Actualizado MainGUI para cargar la nueva pantalla principal - Añadido javafx-maven-plugin en pom.xml para ejecutar la UI - Inyectado MainService en MainScreenController" --- RESUMEN-E3-US1-T1.md | 106 +++++------------- pom.xml | 22 ++++ src/main/java/es/iesquevedo/MainGUI.java | 37 +++--- .../iesquevedo/ui/MainScreenController.java | 90 +++++++++++++++ src/main/resources/fxml/MainScreen.fxml | 31 +++++ .../MainControllerIntegrationTest.java | 52 +++++++++ 6 files changed, 237 insertions(+), 101 deletions(-) create mode 100644 src/main/java/es/iesquevedo/ui/MainScreenController.java create mode 100644 src/main/resources/fxml/MainScreen.fxml create mode 100644 src/test/java/es/iesquevedo/integration/MainControllerIntegrationTest.java diff --git a/RESUMEN-E3-US1-T1.md b/RESUMEN-E3-US1-T1.md index 371f4f5..39eec68 100644 --- a/RESUMEN-E3-US1-T1.md +++ b/RESUMEN-E3-US1-T1.md @@ -1,90 +1,34 @@ -# 📋 RESUMEN EJECUTIVO - E3-US1-T1 -## 🎯 Objetivo -Corregir el error `javafx.fxml.LoadException: Controller value already specified` que impedía ejecutar la aplicación JavaFX. +## 🔄 Actualización - 2026-04-14 ---- - -## ⚡ Cambios Realizados - -### 1️⃣ **Main.fxml** - Agregación de fx:controller -```xml - - -``` - -### 2️⃣ **MainGUI.java** - Refactorización de carga de FXML -**Cambio clave:** Remover `loader.setController()` que conflictaba con FXML -- ✅ Cargar FXML primero (auto-instancia el controlador) -- ✅ Obtener controlador con `loader.getController()` -- ✅ Inyectar servicio con `mainController.setService()` - -### 3️⃣ **MainController.java** - Inyección post-construcción -```java -// Antes: constructor con parámetro (incompatible con FXML) -// Después: constructor sin parámetros + método setService() - -public void setService(MainService mainService) { - this.mainService = mainService; - initialize(); // Reiniciar con el servicio inyectado -} -``` - -### 4️⃣ **MainApp.java** - Consistencia en modo console -Se adaptó para usar el mismo patrón de inyección que MainGUI - -### 5️⃣ **run-app.ps1** - Simplificación de ejecución -Se removieron argumentos de módulo complejos para usar solo classpath simple - ---- - -## ✅ Validación +### Nuevas tareas completadas -| Aspecto | Estado | -|---------|--------| -| 🔨 **Compilación** | ✅ BUILD SUCCESS | -| 🚀 **Ejecución** | ✅ GUI inicia correctamente | -| 📝 **Logs** | ✅ Saludo se carga: "Hello, InazumaGoPrevio!" | -| 💾 **Modo Console** | ✅ Funciona correctamente | +#### E1-US2-T4 - Test de integración con Mockito ---- - -## 🎓 Patrón Implementado - -**FXML Dependency Injection Pattern:** -``` -1. FXML instancia el controlador (constructor sin parámetros) -2. FXML inyecta componentes @FXML -3. Aplicación inyecta servicios (método setService) -4. initialize() se ejecuta automáticamente tras cada inyección -``` - -Este es el patrón estándar recomendado para JavaFX/FXML. - ---- +**Cambios realizados:** +- Añadidas dependencias Mockito en `pom.xml` + - `mockito-core:5.5.0` + - `mockito-junit-jupiter:5.5.0` +- Creado `MainControllerIntegrationTest.java` + - Verifica que `MainController` delega correctamente en `MainService` + - Testea escenario con servicio mockeado + - Testea escenario con servicio null + - Testea inyección de servicio -## 📊 Archivos Modificados +**Validación:** +- ✅ `mvn test -Dtest=MainControllerIntegrationTest` → BUILD SUCCESS +- ✅ Tests run: 3, Failures: 0 +- ✅ Reportes generados en `target/surefire-reports/` -| Archivo | Líneas | Tipo | -|---------|--------|------| -| Main.fxml | 1 | Configuración | -| MainGUI.java | ~15 | Refactorización | -| MainController.java | +6 | Métodos nuevos | -| MainApp.java | 2 | Actualización | -| run-app.ps1 | 2 | Simplificación | +**Archivos modificados/creados:** +- `pom.xml` (dependencias Mockito) +- `src/test/java/es/iesquevedo/integration/MainControllerIntegrationTest.java` (nuevo) --- -## 🏆 Resultado Final - -✨ **Aplicación completamente funcional y ejecutable** -- GUI se carga sin errores -- Inyección de dependencias funciona correctamente -- Código sigue patrones estándar JavaFX -- Aplicación lista para producción - ---- - -**Completado:** 2026-04-08 -**Tarea:** E3-US1-T1 ✅ - +**Estado actual del proyecto:** +- ✅ Compilación: BUILD SUCCESS +- ✅ Tests unitarios: pasan +- ✅ Tests de integración: pasan +- ✅ Pipeline CI: configurado +- ✅ Documentación: actualizada \ No newline at end of file diff --git a/pom.xml b/pom.xml index a4b990e..ce9716b 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,20 @@ firebase-admin 9.8.0 + + + + org.mockito + mockito-core + 5.5.0 + test + + + org.mockito + mockito-junit-jupiter + 5.5.0 + test + @@ -60,6 +74,14 @@ + + org.openjfx + javafx-maven-plugin + 0.0.8 + + es.iesquevedo.MainGUI + + org.jacoco jacoco-maven-plugin diff --git a/src/main/java/es/iesquevedo/MainGUI.java b/src/main/java/es/iesquevedo/MainGUI.java index bd1f7c4..bc4b22d 100644 --- a/src/main/java/es/iesquevedo/MainGUI.java +++ b/src/main/java/es/iesquevedo/MainGUI.java @@ -1,8 +1,8 @@ package es.iesquevedo; import es.iesquevedo.config.AppConfig; -import es.iesquevedo.controller.MainController; import es.iesquevedo.service.impl.MainServiceImpl; +import es.iesquevedo.ui.MainScreenController; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; @@ -18,33 +18,30 @@ public class MainGUI extends Application { @Override public void start(Stage primaryStage) { try { - // Cargar FXML con su controlador - FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml")); - Parent root = (Parent) loader.load(); - - // Obtener el controlador después de cargar el FXML - MainController mainController = loader.getController(); - - // Configuración de servicios + // Load the new main screen FXML + FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/MainScreen.fxml")); + Parent root = loader.load(); + + // Get controller and inject service + MainScreenController controller = loader.getController(); String firebaseUrl = System.getenv("FIREBASE_URL"); var repository = AppConfig.createMainRepository(firebaseUrl); var mainService = new MainServiceImpl(repository); - - // Inyectar dependencias en el controlador - mainController.setService(mainService); - + controller.setService(mainService); - // Crear escena y mostrar ventana - Scene scene = new Scene(root, 600, 400); - primaryStage.setTitle("InazumaGo"); + // Set up stage + Scene scene = new Scene(root, 700, 500); + primaryStage.setTitle("InazumaGo - Pantalla Principal"); primaryStage.setScene(scene); primaryStage.show(); - if (LOGGER.isLoggable(Level.INFO)) { - LOGGER.log(Level.INFO, "Aplicación JavaFX iniciada exitosamente"); - } + LOGGER.log(Level.INFO, "Aplicación JavaFX iniciada - Pantalla principal cargada"); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Error al iniciar la aplicación", e); } } -} + + public static void main(String[] args) { + launch(args); + } +} \ No newline at end of file diff --git a/src/main/java/es/iesquevedo/ui/MainScreenController.java b/src/main/java/es/iesquevedo/ui/MainScreenController.java new file mode 100644 index 0000000..8779944 --- /dev/null +++ b/src/main/java/es/iesquevedo/ui/MainScreenController.java @@ -0,0 +1,90 @@ +package es.iesquevedo.ui; + +import es.iesquevedo.service.MainService; +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ListView; +import javafx.scene.control.Alert.AlertType; + +import java.util.Arrays; +import java.util.List; + +public class MainScreenController { + + @FXML + private ListView playersListView; + + @FXML + private Button randomMatchButton; + + private MainService mainService; + + // Called by MainGUI after loading FXML + public void setService(MainService mainService) { + this.mainService = mainService; + // Once service is set, we could load real data from Firebase + // For now, load mock players + loadMockPlayers(); + } + + @FXML + public void initialize() { + // Initialization if needed; actual data loading happens in setService + } + + private void loadMockPlayers() { + // TODO: Replace with real data from Firebase via MainService / PlayerRepository + List mockPlayers = Arrays.asList("Jugador1", "Jugador2", "Jugador3", "Jugador4", "Jugador5"); + playersListView.getItems().setAll(mockPlayers); + } + + @FXML + private void onRandomMatch() { + // Simulate random matchmaking + showInfo("Emparejamiento Aleatorio", "Buscando oponente..."); + // In a real implementation, you would call a matchmaking service and navigate to game screen. + // For demo, we simulate a found match after 1 second. + new Thread(() -> { + try { Thread.sleep(1000); } catch (InterruptedException e) {} + Platform.runLater(() -> { + showInfo("Partida encontrada", "Has sido emparejado con OponenteAleatorio. ¡Comienza la partida!"); + // Here you would load the game board screen + }); + }).start(); + } + + @FXML + private void onRefreshPlayers() { + loadMockPlayers(); + showInfo("Actualizar", "Lista de jugadores actualizada."); + } + + @FXML + private void onChallengeSelected() { + String selected = playersListView.getSelectionModel().getSelectedItem(); + if (selected == null) { + showWarning("Atención", "Debes seleccionar un jugador de la lista."); + } else { + showInfo("Retar", "Has retado a " + selected + ". Esperando respuesta..."); + // Here you would send a challenge via Firebase + } + } + + private void showInfo(String title, String message) { + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); + } + + private void showWarning(String title, String message) { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); + } +} \ No newline at end of file diff --git a/src/main/resources/fxml/MainScreen.fxml b/src/main/resources/fxml/MainScreen.fxml new file mode 100644 index 0000000..5c1c6c5 --- /dev/null +++ b/src/main/resources/fxml/MainScreen.fxml @@ -0,0 +1,31 @@ + + + + + + + + + + + +