Duda con Java Swing

0nLy

Hola buenas, estoy haciendo un proyecto para clase, (estoy empezando a programar así que no me metais mucha mierda xD)

Resumidamente, tengo un programa igual que el mítico "Quien quiere ser millonario", te aparece una pregunta en la pantalla y 4 botones con opciones A) B) C) y D)

Tengo un array con preguntas, una matriz con las posibles respuestas de cada pregunta(4 posibles para cada pregunta), y otro array con las respuestas correctas de cada pregunta.
El caso es que quiero que cuando el jugador pulse el botón con la respuesta correcta, el botón automáticamente se ponga de color verde, y no hay forma humana de conseguirlo.

Os dejo por aquí el código por si podeis echarme una manita, os lo agradecería^^

private void comprobarRespuesta(){
               if (?????) {
                    btnB.setBackground(Color.green);
               }
}
Zoth

¿Comparando la respuesta introducida por la que debería ser no te deja?

RaCe

pues entonces básicamente lo que quieres es que tu condición haga algo así:

if ( opcionElegida == opcionCorrecta )

y lo que irá dentro de esas variables ya depende de como hayas estructurado tus datos internamente

péleate un poco más hijomío que tampoco es tan inhumano

PD: es java, es probable que en vez d usar == lo que te interese mas es el metodo equals(), pero vamos, misma idea

NoRelaX

Vaya jaleo de planteamiento para las preguntas/respuestas.
¿Qué pasa cuando haces click sobre un botón? ¿Te devuelve una posición de la matriz? Supongo que tendrás que comprobar si el valor de esa posición coincide dentro del array de respuestas correctas.

1 respuesta
0nLy

#4 Eso es lo que no sé plantear, no sé que hacer exactamente cuando haces click en un botón. No sé tampoco si hay alguna forma de hacerlo más corto
Para una pregunta sería fácil, el problema es que no sólo quiero una pregunta, quiero mínimo 15 ó 20.
Entonces no sé si tengo que hacer un Case con 15-20 opciones, y que cada pregunta entre en su case para ver la opción correcta o cómo...

edit: algo así que tal?


//Array respuestas correctas de cada pregunta
        respCorrecta[0] = 1;
        respCorrecta[1] = 2;
        respCorrecta[2] = 0;
        respCorrecta[3] = 3;


private void comprobarRespuesta(int pregunta) {
    switch (pregunta) {
        case 0:
            if (opcionCorrecta() == 1) {
                btnB.setBackground(Color.green);
            }
        case 1...
            
    }

}

private int opcionCorrecta() {
    for (int i = 0; i < 20; i++) {
        switch (i) {
            case 0:
                return 1;
            case 1:
                return 0;
            case 2:
                return 2;
            case 3:
                return 3;

        }
    }
    return -1;
}

el bucle for de 20 en teoría es para recorrer las supuestas 20 preguntas que va a tener el juego

0nLy

sry por el doblepost, el código entero del ejercicio ahora mismo es este:

spoiler

Ahora mismo, directamente el botón con la opción correcta sale en verde directamente sin pulsar ningún botón

2 respuestas
NoRelaX
#60nLy:

Ahora mismo, directamente el botón con la opción correcta sale en verde directamente sin pulsar ningún botón

Claro, porque estás llamando al método para comprobar desde inicioJuego.
Yo le pegaría otra pensada, seguro que puedes hacerlo mucho más sencillo.

1 respuesta
0nLy

#7 Es verdad, buah, menudo puto lío me estoy haciendo...

Llevo un rato pensando y estoy en una de esas ocasiones en las que te va a explotar la cabeza XD

1 respuesta
Diward

#6 El metodo "private int opcionCorrecta" no hacer return 1 siempre en la primera iteración?

Solo mirando ese método ya se ve que la cosa está muy verde, es bastante desprosito.

1 respuesta
NoRelaX

#9 Correcto.

#8 Mi consejo es que vuelvas a replantearte cómo solucionarlo "desde abajo", o sea, piensa otra forma de guardar y organizar las preguntas con sus respuestas para después poder manejarlas con más facilidad. A lo mejor te conviene crear una clase Pregunta y una clase Respuesta.

2 respuestas
KinachO

Si de verdad estás aprendiendo a programar, deja el swing que es sidita y ponte con java fx que le da mil vueltas!!

1 1 respuesta
0nLy

#10 Eso he pensado, el problema es que cada pregunta tiene 4 posibles respuestas y solo 1 correcta. Es eso lo que no sé plantear ni como recogerlo ni nada. Estoy muy verde todavía, igual me he metido en un fregao superior a mi XD

seguiré dandole vueltas, muchas gracias ^^

#11 Eso díselo a mi profesora :&

NotToBit

Tengo bastante oxidado el JSwing, pero a ver si te puedo ayudar.

Lo primero darle la razón a #10. Intenta resolverlo con Objetos. Al principio cuesta, pero luego te hace la vida más fácil.

Crea una clase Pregunta que pueda almacenar el texto de la pregunta, sus 4 respuestas y un dato qeu le indique cuál es la correcta. Hay muchas formas de hacerlo, pero en todas vas a necesitar acabar accediendo a 1 String para el texto pregunta y 4 Strings para los textos respuesta. El dato que te indique la respuesta correcta va a depender de como organizces la clase: si las respuestas están en un array, puede ser un entero que te indique un índice de ese array.

Luego vas a necesitar darle comportamiento a la clase. Necesitas como mínimo getter y setter para el texto pregunta, alguna forma de poder añadir y consultar textos de respuestas y un método que de diga si una respuesta parada por parámetro es correcta (el indice, el texto de la respuesta,... como quieras, puede devolverte un booleano).

Como ya no tienes arrays de String, ahora necesitas crear las preguntas y añadirlas a una estructura de datos, puede usar una array de la clase pregunta. Vas creando las preguntas una por una y setteando su contenido (constructor vacío + setters o constructor con todos los parámetros, como veas).

Por último, necesitas que al pulsar cada botón, se localice la Pregunta correcta y se le pregunte si la respuesta es correcta. Supongo que esos métodos btnBActionPerformed están siendo llamados desde los action listeners que asignas a cada botón en el cuerpo de initComponents(). No recuerdo muy bien si JSwing te permitía obtener datos sobre el botón pulsado, pero en caso de que no se pudiese:
necesitas que cada método llamado desde cada action listener pueda identificar su pregunta, identificar su respuesta e identificar su botón. Por lo tanto, una posible solución es que cada método obtenga su pregunta desde un array de preguntas a partir del índice (que como no sé si puedes obtenerlo a partir del botón, estaría hardcodeado en el método), que invoque al método de la pregunta que te permite consultar si una respuesta es correcta (con el índice de la respuesta hardcodeado también, por ejemplo) y que si ese método devuelve el valor adecuado cambie el atributo de color del botón.

Hay muchas otras posibles soluciones, seguramente alguna sea mucho más elegante siendo capaz de obtener datos del objeto que origina el evento click. También te digo que ahora mismo estás liándote mucho con el bucle for que tienes en opcionCorrecta() y que la verdad es que no hace nada.
Date cuenta de los arrays permiten acceso directo, con lo cual no deberías necesitar hacer ningún bucle mientras sepas el índice al que quieres acceder. En tu caso puedes acceder directamente tanto a la pregunta como a la respuesta. Si aún así quieres utilizar un bucle, piensa que necesitas saber cuando pararlo, por lo que tendrías que pensar: variable que quieres evaluar en cada iteración, valor que debe tener para detener la ejecución del bucle, dato que deseas obtener cuando se cumpla la comparación, valor que deseas obtener si el bucle termina sin cumplir la comparación.

Espero con esto y dándole alguna vuelta consigas darle solución.

1 respuesta
Zerokkk
  • Crea una clase Pregunta, en la cual tienes la pregunta, un array de posibles respuestas, y el índice de la correcta.

  • Pinta dinámicamente en un JPanel (por ejemplo) el button group con los JRadioButtons, JButtons o lo que quieras. Utiliza uno de los layouts que hay, y utilízalo para representar cada uno de tus objetos Pregunta.

  • Crea un ArrayList (por ejemplo) con tus objetos Pregunta, y un método al cual pasas un índice de pregunta e índice de respuesta, y accede mediante ellos a la pregunta que deseas, y comprueba con el de respuesta, si has acertado o no. Este método deberá devolverte un simple boolean.

  • En el evento click del botón, haz una llamada a ese método.

Bien, ahora te toca cambiar cómo el botón procesa tu click. Para ello deberás hacer lo de siempre en Swing: crear un objeto que hereda de JButton (o la clase que quieras), y sobrescribir el método que renderiza la acción que quieres tomar. Yo lo he tenido que hacer un par de veces con las tablas, donde es muy mítico tener que cambiar el render de una celda, por ejemplo.

Te he encontrado un topic de Stackoverflow donde cambian el color de un JButton, para que veas qué método tienes que sobrescribir. El resto ya está dicho.

0nLy

Bueno, sorry por no responderos antes, he estado bastante liado con exámenes y este puto proyecto y tal. Gracias a los que me habeis molestado en ayudarme, auqnue no os haya respondido os leí en su día ^, y gracias a los que me habeis metido mierda gratuitamente aun sabiendo que estoy súper verde con esto todavía.

Al final lo conseguí haciendo una clase "pregunta" como dijisteis por ahí arriba y matandome la cabeza lo que no está escrito.

Por si quereis echarle un ojo y ver que tal me ha quedado (y echarme la bronca si quereis) os dejo un enlace con el proyecto para que lo abráis desde alguna IDE y lo veais.

https://www.mediafire.com/folder/pr4865tn9ot0r/nava

La verdad que estoy bastante contento con el resultado (aunque puede mejorarse una barbaridad).
Para ser mi primer trabajo medianamente "completo" yo creo que no está mal la verdáh.
Ya me contaréis si alguno lo probais ^^

2 3 respuestas
Lecherito

#15 Usa git para enseñarnos el código no eso lol

Zerokkk

#15 Le he echado un vistacito muy breve. Hay muchas cosas que podrían estar mejor hechas, diseños un poco feos, pero bueno, falta de experiencia. Según vayas aprendiendo a adaptarte a programar con orientación al objeto, aprovechar polimorfismo y tratar de lograr modularidad, optimización y encapsulamiento, irás haciendo aplicaciones mejores. Y sobretodo, más fáciles de mantener.

Ahí van unas observaciones rápidas, aunque me faltan algunas cosas más genéricas:

spoiler
1 1 respuesta
m4andg4

#17 Veo más sencillo y "escalable" tener una clase pregunta que se construya con un string pregunta más array de 4 Strings (contenedores de las respuestas) más un entero no mayor que 4 que señale la correcta.

Cada pregunta como un objeto distinto, que luego puedes expandir desde el main(), meterlos en una Lista y aleatorizarlas... mas modular y sin tener que tocar el código de la clase más.

Algo así se me ocurre:

Clase Pregunta 0.2
Programa main() 0.2

Corregido código inútil con la versión 0.2
Bueno, en vez de usar arrays propiamente dichos, ArrayList sería mucho más comodo a la hora de introducir los Strings y tal. Incluso podrías crear metodos static como:

public static String[] creaArrayRespuestas(String ... respuestas); 

que te devuelva hecho el array de respuestas y facilitar la creación del programa y cosas así por dar ideas.[/s]

#13 shiet :/

3 respuestas
FuckingEnemy

#1 Lo de meter swing es cosa tuya o te lo a dicho el profesor que teneis que usarlo? Es que me estraña que primero os enseñen u os digan que teneis que usar swing cuando no os ha enseñado POO, porque te resolveria la vida desde un principio.

Yo crearia tres clases, respuesta, pregunta y carrusel.

  • Respuesta: con dos atributos, un string que seria la respuesta y un booleano indicando si es correcta o no.

  • Pregunta: con un string de la pregunta y un array de respuestas.

  • Carrusel: Con un array de preguntas y un int que seria el tamaño del array. Y la usaria como "base de datos" de preguntas y respuestas.

Algo asi .

Carrusel

y ya solo en el main tienes que hacer:

Carrusel listado = new Carrusel();

Luego para la parte de la interfaz la crearia en otra clase aparte del main y ya solo tienes que ir llamando conforme te hagan falta las cosas y se te queda un codigo mas limpio y mas facil de entender y de encontrar fallos, que si lo metes todo en una misma clase.

1 respuesta
NotToBit

#15 Tienen razón en una cosa que te comentan por aquí. En éste caso (y en general) es conveniente que trates a la clase Pregunta como una pregunta singular, no como si fuese Preguntas, y que luego utilices una estructura de datos para almacenarlas todas. E intenta que el nombre de la clase sea descriptivo: si va a contener todas las preguntas, llámala Preguntas, si se llama Pregunta, que sólo contenga una.
Una idea muy importante que te puede ayudar a comprenderlo de forma natural, es que la programación orientada a objetos (OOP) busca modelar y representar el mundo real (o contexto del problema que intentas resolver) de una forma natural.
Piensa en "programar" un coche con ruedas: Creas una clase rueda que representa una sola rueda y le das comportamiento (hinchar, girar, por decir algo), luego creas una clase coche y le pones 4 atributos rueda (y le das comportamiento al coche, por ejemplo acelerar). Date cuenta de que no estamos modelando toda la complejidad de un coche real, sólo la parte que necesitamos. Por ejemplo, mañana puedo necesitar que el coche tenga un acelerador, un freno, un freno de mano,... O igual no.
Puede darse el caso en el que necesites crear una clase "en plural", como has hecho con las Preguntas, pero es muy raro que directamente ignores la clase Pregunta que contiene una sola pregunta. Te pongo un ejemplo que utilizo últimamente:

Estás haciendo un juego 2D con el escenario en cuadrícula (vista lateral, superior o isométrica, da igual), y tienes imágenes de diferentes trozos del escenario (un trozo de suelo, una escalera, un trozo de rampa, etc, que llamamos Tiles) con los que componerlo. A esa composición la llamamos Mapa de Tiles. Podrías hacer el equivalente a lo que hiciste tú, crear una clase Tiles y dentro meter toda la representación del mapa de tiles.
Pero me resulta mucho más útil crear una clase Tile que contenga la información básica de un sólo tile (coordenadas, imagen, dimensiones, area de colisión, etc) y que me deje trabajar con él de forma individual (dibujar, actualizar, destruir, etc).
Ahora necesito tener en algún sitio la colección de tiles que representa mi escenario. Me puede servir simplemente un array de arrays de tiles (o array bidimensional) tal que Tile[][] tileMap. Y la cosa se puede quedar ahí sin ningún problema, cuando necesite algo, recorro el array, o voy a la posición que necesite e interactúo con el tile y listo. Pero nos ponemos en la situación de que yo ahora lo que quiero es que el tileMap encapsule las operaciones referentes a sí mismo.
Creo una clase TileMap, que contenga un array bidimensional de tiles y empiezo a darle comportamiento (inicializar desde fichero, dibujar todos los tiles, actualizar todos los tiles, destruir area, modificar tile, etc) y atributos que me puedan servir (area que se dibuja, loo que sea).
Cada Tile sabe como dibujarse a sí mismo, y el TileMap sabe a cuántos, cuales y en qué orden decirles que se dibujen.

Lo que te quiero decir con todos éstos ejemplos, es que tienes que intentar hacer representaciones sencillas y coherentes. Fragmenta los problemas en partes e intenta encajar esos fragmentos para que formen objetos sencillos de forma que te faciliten el trabajo. A partir de esos objetos sencillos, puedes crear otros objetos más grandes que los contengan y que se vayan encargando de tareas más generales.

#18 xDDD

#19 Suena a que está estudiando un módulo. A mi fué como me lo enseñaron cuando hice uno hace ya unos añetes: primero nos metían bases de programación y resolución de problemas (y aritmética de punteros) usando la parte más simple de C++, pero sin ver absolutamente nada de OOP; y luego enseñaban cuatro pijadas de OOP (casi ni raspar la superficie) y nos tiraban contra C# a hacer apligaciones de gestión. Me han comentado que ahora empiezan desde el principio con OOP y no se centran tanto en la parte de coger tablas en resolver problemas, pero que siguen buscando lo mismo: que empieces a hacer cosas rápidamente.
En mi caso y el de mis compañeros el resultado fué que al terminar éramos capaces de crear programas de gestión que funcionaban, pero que eran clases monolíticas de 10.000 lineas de código. La única concesión que hacíamos a la modularidad era intentar separar el código en funciones con cierta coherencia y el escaso conocimiento sobre OOP sólo nos servía para ser capaces de usar las clases de la interfaz y poco más. Luego ya por mi cuenta me metí fuerte con Objetos y empecé a usar clases como dios manda.
Ojo, seguro que no en todos sitios enseñan así el módulo, sólo describo mi experiencia.

2 respuestas
Zerokkk

#18 Yo me he estado ciñiendo a su diseño, que como bien dije es erróneo y está lejos de seguir los principios de POO. Básicamente, por lo que se puede ver, su clase "Pregunta" hace referencia a cada uno de los pares pregunta/respuesta que le van llegando al jugador, más que a cada pregunta como tal. Siendo así, ese array de preguntas tan feo está mejor siendo static, pese a que toda la base esté un poco errática. Por motivos de optimización más que nada.

Lógicamente para dejar bien su proyecto, habría que reestructurarlo desde 0.

#20 Efectivamente, en los ciclos superiores ahora al principio te ponen POO. Pero vamos, que tampoco se meten demasiado, y la mayoría de cosas aprendes a utilizarlas con experiencia o formándote a mayores (yo en mi empresa gestiono varios cursos, uno de ellos de programación orientada a objetos, y para hacerlo lo mejor posible, he tenido que formarme bastante, especialmente para saber donde cuadrar clases abstractas e interfaces).

2 respuestas
FuckingEnemy

#20 #21 Joder, pero que menos que enseñen lo basico de POO, que hacer este ejercicio la dificultad es pelearte con el swing.

Basicamente la mayoria de aplicaciones que hago son orientadas a objetos y cuando veo que me sale algun metodo tocho estoy tirando de la extracion de metodos del eclipse, no me quiero imaginar lo que os tenian que salir a vosotros xd.

2 respuestas
Zerokkk

#22 A día de hoy todo tiene que ser orientado a objetos, todo o casi todo xD. O como mínimo hacer una orientación a prototipos (con JS).

Que te salga un método muy extenso no viola SOLID/OOP, a menos que contenga trozos de código reutilizables en el propio método o fuera (lo cual es muy habitual), que entonces se encapsula un poco y ya.

Y bueno, swing no tiene mucha cosa, lo malo es que muchas veces se peca de utilizar la vista como controlador y no es fácil salir de esta práctica. Lo demás... no me parece particularmente difícil en swing, quitando algún método raruno de estos que tienes que sobrescribir para ponerle un colorcito distinto a esa celdita.

1 respuesta
FuckingEnemy

#23 Na, si lo de extraer es porque luego me resulta mas facil leer, entender o encontrar fallos en el codigo, porque si no luego no se ni lo que estoy leyendo.

Y lo del swing pues si, realmente no es nada del otro mundo, pero me resulta extraño que primero enseñen a utilizar este tipo de paquetes que el hecho de enseñar algo tan basico y que como dices, se usa para todo o casi todo.

NotToBit

#21 #22 Lo ideal sería que estuviesen 3 meses mínimo metiéndoles caña con objetos y resolución de problemas, pero tal como están los módulos enfocados, lo que quieren es que empieces a hacer programas rápidamente. Luego claro, yo hacía los programas literalmente en una sóla clase de 10.000 ó 15.000 lineas... xD

1 respuesta
Zerokkk

#25 Hombre a nosotros nos dieron lo básico pero a la hora de programar cosas, se basaban más en la funcionalidad que en cómo estuviera diseñado... yo empecé a usar polimorfismo a saco años después de acabar el ciclo, antes ni lo tocaba, vaya xD.

1 respuesta
m4andg4

El horror de encontrarse una main class con todo el codigo lol, como si esto fuera C o algo.

0nLy

Muchas gracias a todos, tengo que decir que estoy empezando y la mayoría de las palabras que utilizais me suenan a chino xD

En septiembre no tenía absolutamente ni idea de java, así que hacer esto para mi ya es un logro, vamos avanzando porquito a poco.

He tenido mogollón de problemas con el código y tuve que hacer chapuzas para arreglarlo y la verdad que ha quedado feísimo al final, pero bueno.

Decir que con la programación orientada a objetos llevo 2 meses, nos han explicado lo básico, clases, herencia, abstractas y poco más.

Una duda: Solo leo por ahí que swing es una mierda obsoleta y tal... Qué es lo que se usa ahora? No nos han explicado nada y la verdad que no estoy muy puesto en el tema y me gustaría ponerme a indagar y hacer cosillas por mi cuenta en el verano.
Yo no conozco otra cosa que no sea trabajar con netBeans y swing, si me pudierais explicar por encima el estándar de hoy en día os lo agradecería.

Bueno, muchas gracias a todos por molestaros en explicarle las cosas a un nub :)

pd: #26 miss u

1
Lecherito

#18 Me hace gracia que uses new String(pregunta) cuando String ya es inmutable de por sí xDD

1 respuesta
m4andg4

#29 tienes razón jaja las manías y costumbres contra el aliasing

Usuarios habituales

  • m4andg4
  • Lecherito
  • 0nLy
  • Zerokkk
  • NotToBit
  • FuckingEnemy
  • NoRelaX