Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Mensajes - Kabuto

Páginas: 1 ... 24 25 26 27 28 [29] 30 31 32 33 34 ... 50
561
Hay algunas cosas que no veo claras.

Citar
Clase Botón
Atributos
Int valor: Este atributo nos servirá para identificar el color que tiene como valor
ese momento el botón. Este valor esta codificado entre 1 y 6, que se corresponderá
con su posición en el Vector botones
, y según ese valor, se decidirá su color.

Ahí parece dar a entender que hay relación entre el valor del Boton y su posición en el vector, pero no es así.
Yo quitaría la parte marcada en negrita.



Citar
Public void rotarValor(): Este método nos permite darle un ciclo al valor, es
decir al llegar al máximo , comenzamos de nuevo desde el principio, en este caso sería
llegar al valor 6 , reseteamos al valor 1. Y le metemos el método cambiarColor para
que se resetee el valor al llegar a 6.

Esto tampoco queda claro, dicho así parece que sea cambiarColor quien resetea el valor.
Yo lo cambiaría por:
Citar
Public void rotarValor(): Este método nos permite darle un ciclo al valor, es
decir al llegar al máximo , comenzamos de nuevo desde el principio, en este caso sería
llegar al valor 6 , reseteamos al valor 1.
Cada vez que se altera el valor, se invoca al método cambiarColor para que actualice el color mostrado en pantalla y se corresponda con el nuevo valor.



Citar
Public void actionPerformed (Actionevent e): Para que todo esto ocurra le
metemos el método actionPerformed para que el usuario cuando clickee , dentro
escribimos el método rotarValor().

Esto no está mal, pero creo que se podría mejorar:
Citar
Public void actionPerformed (Actionevent e): Para que todo esto ocurra le
metemos el método actionPerformed para que el usuario cuando clickee , se llama al método rotarValor() para pasar al siguiente valor y color.



Citar
Clase combinación
Atributos
Public int [] combinacion: Es el vector generado aleatoriamente
Public int intentos: El número de veces que se puede jugar
Public int muertos: Contabiliza cuando el color y la posición en combinación[]
es la misma que la que el usuario elige y se guarda en vector botones [4].

Public int heridos: Contabiliza cuando el color es acertado, pero la posición en
botones [4] no es la misma que en combinación[4]

La explicación es mejorable:
Citar
Clase combinación
Atributos
Public int [] combinacion: Es el vector generado aleatoriamente
Public int intentos: El número de veces que se puede jugar
Public int muertos: Contabiliza los "muertos". Un "muerto" se produce cuando un elemento de botones[] coincide en valor y posición con un elemento de combinacion[].
Public int heridos: Contabiliza los "heridos". Un "herido" se produce cuando un elemento de botones[] coincide en valor, pero no en posición, con un elemento de combinacion[].



Citar
Public Combinacion(): Es el constructor, donde inicializo el vector, meto el
método generaCombinacion(), inicializo también los intentos a 0 y con el boolean
resuelto = false, controlo los intentos.
No es el boolean quien controla los intentos:
Citar
Public Combinacion(): Es el constructor, donde inicializo el vector, meto el
método generaCombinacion(), inicializo también los intentos a 0 y con el boolean
resuelto = false, controlo si la combinación secreta ha sido resuelta o no.



Esto que viene a continuación, es quizás lo más difícil de explicar, y lo has explicado muy bien.
Pero hay una cosita que llama la atención:

Citar
Public String evaluar (Integer [] colores): Con esto evaluamos si ha habido
muertos y/o heridos según las reglas del Mastermind. He usado un array de clase
Integer en lugar del tipo primitivo int, por que con Integer puedo dar valores null o -1 a
los elementos del array, porque cuando vaya a comparar los colores, si al comparar
dos posiciones de dos arrays ( combinación y el de selección de usuario) se producen
muertos o heridos, ya no se consultarán más esas posiciones mientras se sigue
evaluando, por eso las marco con valor null o -1. El problema que tiene esto es que no
puedo trabajar directamente con el array de combinación del usuario, puesto que
destruiría su combinación, para resolver este problema hago una copia de
combinación y trabajo sobre esa copia.
Así este método se encarga de evaluar recibiendo como parámetro un array con la
selección que ha hecho el usuario, comparo con la copia de la combinación generada
aleatoriamente, contabilizo si hay muertos y heridos y devuelvo un String con el
resultado.
Primero contabilizo muertos recorriendo ambos arrays a ver si en la misma posición,
coinciden los colores.
Segundo busco herido en las posiciones que no hagan sido puestas a null o -1 (las que
no hayan generado muertos), ya que los heridos son colores escogidos que sí constan
en la combinación, pero no en la misma posiciones.


Yo en mi código use Integer para poder poner valores null y "marcar" elementos que ya no deben ser consultados.
Tu en cambio, pusiste valores -1.

Ambas formas funcionan, eso no es problema.

Pero al explicarlo en la documentación, quizás mejor no mencionar lo de poner valores null, puesto que en realidad no lo estás haciendo en tu código.

Por eso en realidad, en tu código no necesitas usar vectores Integer, puedes usar todos como vectores int.

La diferencia entre int e Integer, es que int es un "dato primitivo", es decir, una variable a la "antigua usanza" que Java hereda del lenguaje C (Java es un derivado de C) y básicamente es un apuntador a una dirección de memoria.

Integer es una clase "moderna", ya pensada para la Programación Orientada a Objetos.
Es mucho más que un puntero de memoria, permite tener métodos, constructores, herencias, polimorfismo, valor null, etc...

En mi caso, me interesó usarlo únicamente por poder darles valor null.
Pero perfectamente podría haber usado el tipo primitivo int y haberles dado valor -1

Bueno, valor -1 , o cualquier otro valor que no estuviera entre 1 y 6.
Los elementos de los vectores que son "válidos", únicamente pueden tener valores entre 1 y 6.
Si quiero marcarlos como "no válidos", o "no consultables" mejor dicho, me basta con darle un valor cualquiera que este fuera del rango entre 1 y 6.
Le podría dar valor 0, -34, 7, 1000,....

La cuestión era idear una fórmula simple para "marcar" elementos de los vectores que ya no quiero seguir consultando, porque ya me habían dado un "muerto" o un "herido".



En clase PanelColores:
Citar
Public PanelColores (Combinacion c): Es el constructor de la clase, donde añado
como atributo una referencia al objeto combinación que será instanciado en la clase
principal JFrame Mastermind.
Añado la creación de los 3 paneles dentro del propio constructor y añado como
atributo una referencia al objeto combinación

Está bien, quizás yo añadiría una pequeña aclaración:

Citar
Public PanelColores (Combinacion c): Es el constructor de la clase, donde añado
como atributo una referencia al objeto combinación que será instanciado en la clase
principal JFrame Mastermind.
Teniendo una referencia al objeto combinacion, cada PanelColor es capaz por sí solo de evaluar la jugada del usuario con la combinación secreta.
Añado la creación de los 3 paneles dentro del propio constructor y añado como
atributo una referencia al objeto combinación

562
Comunidad / Re: Duda Java
« en: 06 de Diciembre 2020, 22:35 »
Hola Orlando.

Puedes usar un String para ir concatenando ("sumando") los nombres que se van introduciendo.
Entre cada nombre puedes intercalar un salto de línea "\n" para que cada nombre insertado se muestre en una línea separado de los demás.

Si quieres seguir tratando este tema, mostrando tu código y tal..., hazlo creando un nuevo tema en esta otra sección.

Esta sección donde estamos, es únicamente para presentaciones.

Un saludo.

563
No te preocupes por usar mi código, pero sobre todo asegúrate de entender bien que hace cada línea.

Sobre tu programa, muy bien. Has añadido los mensajes tras finalizar partida.

Solo tiene una pega, cuando se elige volver a jugar lo que se hace es reinstanciar un nuevo juego completo, sin que se cierre el anterior.
Y como el anterior es quien hace la instancia, en realidad no se puede cerrar.
Esto implica que si elijo rejugar 20 veces.., tendré en memoria 20 juegos MasterMind.., y esto no es óptimo...

Una forma de solucionarlo sería, en lugar de abrir un nuevo juego, reiniciar el juego actual para que comience todo desde el principio, botones reactivados, seteados a valor 1, nueva   combinacion, contadores a 0, etc....

Esto va a implicar añadir métodos a las clases que hemos creado, para que cada una sepa como debe reiniciarse.

A la clase Boton habrá que darle un método para que recupere el valor inicial de 1 y adopte el color correspondiente:

Código: [Seleccionar]
public void reset() {
valor = 1;
cambiarColor();
}

A PanelColores un método que recorra los botones para dar orden de resetearlos, reactive todos los botones que habían sido desactivados durante el juego y limpie los campos de texto para que vuelvan a estar vacíos.

Código: [Seleccionar]
    public void resetPanel() {
    //Botones reinician valor
    for (int i = 0; i < botones.length; i++)
            botones[i].reset();
    //Botones se reactivan
    botonesActivos(true);
    //Limpiamos campo de text
    txtResultado.setText(null);
    }

A Combinación un método similar, que genere nueva combinación y reinicie contadores.
Código: [Seleccionar]
    public void resetCombinacion() {
    generaCombinacion();
    intentos = 0;
    muertos = 0;
        heridos = 0;
        resuelto = false;
    }

Hecho esto, ahora nos vamos a encontrar con unos problemas muy interesantes, que pueden servir para aprender cosas.

Ahora mismo los objetos de la clase PanelColores ya tienen un método para reiniciarse.
Pero resulta que no podemos pedirle que los usen  :o
¿Por qué?
Porque hemos creado objetos "desreferenciados", es decir, no les hemos dado una referencia que poder usar para acceder a ellos.
Simplemente dimos orden de crearlos con new PanelColores() y meterlos en la interfaz.
Pero no tienen un "nombre" de variable asignado para "hablarles" y pedirles que hagan cosas.
Existen, tenemos 10 objetos PanelColores, pero al no tener referencia, no podemos acudir a ellos

Citar
for (int i = 0; i < 10; i++)
        {//Con esto replico el panelColores que contiene los 3 paneles, 10 veces
            panelesBotones.add(new PanelColores(combinacion));
            add(panelesBotones);
        }

Si ahora queremos poder pedirles que se reinicien con el nuevo método que le hemos dado, necesitamos darles una referencia a la que poder acudir.
Como son muchos, lo mejor es referenciarlos usando un vector, así con un bucle podemos acceder a todos ellos con solo un par de líneas.

Así que a la clase MasterMind agregamos un vector como atributo para referenciar estos paneles.

Citar
public class MasterMind extends JFrame
{
   
    Combinacion combinacion;
    PanelColores[] pnColores;

    public MasterMind()
    {
        combinacion = new Combinacion(this);
        pnColores = new PanelColores[10];
       
        JPanel panelesBotones = new JPanel();
        panelesBotones.setLayout(new BoxLayout(panelesBotones, BoxLayout.Y_AXIS));
        //Layout simple que me permite colocar los elementos en forma vertical ;)
        for (int i = 0; i < 10; i++)
        {//Con esto replico el panelColores que contiene los 3 paneles, 10 veces
           pnColores[ i] = new PanelColores(combinacion);
            panelesBotones.add(pnColores[ i]);
            add(panelesBotones);
        }

¡Bien!
Ya podemos "hablar" con esos paneles, nos basta con un bucle, un simple FOR EACH dentro de un método para cuando queramos resetear los paneles.
Añadimos también este método a la clase MasterMind

Código: [Seleccionar]
    public void resetear() {
    for (PanelColores panel: pnColores)
    panel.resetPanel();
    }

Ahora, hay que decidir en qué momento les decimos a estos paneles que han de resetearse.
Lo lógico es hacerlo en el switch que hay dentro de la clase Combinación, ahí donde tu dabas orden de crear un nuevo MasterMind.

Citar
    public void Respuesta()
    {
        resp =JOptionPane.showConfirmDialog(null, msjRepetir, msjTitulo, JOptionPane.YES_NO_OPTION);
            switch (resp) {
                case 0:
                    new MasterMind();
                    break;
                case 1:
                    System.exit(0);
                    break;
                default:
                    System.exit(0);
                    break;
            }
    }
Como ya no vamos a crear un nuevo juego, sino resetear el juego actual, esa línea marcada en rojo la vamos a sustituir por otras dos líneas.
Una, para llamar al método que resetea a la clase Combinación
Y otra línea, para pedirle a la clase MasterMind, que resetee sus paneles de colores.

Pero, aquí surge un nuevo problema. Estamos dentro de la clase Combinación, y esta clase no tiene forma alguna de comunicarse con la clase MasterMind.

Las clases y los métodos/funciones tienen una cosa que se llama "ámbito"(scope), lo que viene a ser su área de influencia.
La clase Combinación puede influir en todo lo que está dentro de ella, pero no en lo que está "fuera".

De hecho, Combinación está dentro de MasterMind (es uno de sus atributos) así que MasterMind si puede influir en Combinación.
Pero no al revés, así que Combinación no puede pedirle a MasterMind que reinicie sus paneles.

A no ser que abramos un canal de comunicación.
Podemos hacer que Combinación también tenga un atributo MasterMind, y al construir un objeto Combinación, este reciba una referencia del objeto MasterMind.
Así ambas clases forman parte del ámbito de la otra, y pueden influirse mutuamente.

A Combinación le añadimos esa referencia a Mastermind como atributo, y la recibirá por su constructor

Citar
public class Combinacion {
   
    public int [] combinacion;
    public int intentos;
    public int muertos;
    public int heridos;
    public int resp;
    public boolean resuelto;
    public String resultado;
    public final String msjTitulo = "MASTERMIND BY JB";
    public final String msjGanar = "Enhorabuena, ¡ GANASTE ! ";
    public String msjIntentos = "UPS!, HAS GASTADO LOS 10 INTENTOS";
    public String msjRepetir = "¿PROBAMOS DE NUEVO?";
   
    MasterMind juegoMM; //Referencia a la clase principal
   
    public Combinacion(MasterMind mm)
    {
        combinacion = new int[4];
        generaCombinacion();
        //Le meto al constructor el metodo
        intentos = 0;
        resuelto = false;
        //Con esto controlo los intentos;
       
        juegoMM = mm;
    }

Y como ahora ya tenemos referencia a MasterMind, ya podemos "hablarle" y pedir que resetee sus paneles cuando el jugador quiera repetir partida.

Citar
    public void Respuesta()
    {
        resp =JOptionPane.showConfirmDialog(null, msjRepetir, msjTitulo, JOptionPane.YES_NO_OPTION);
            switch (resp) {
                case 0:
                   resetCombinacion();
                   juegoMM.resetear(); //Indicamos que hay que reiniciar los paneles

                    break;
                case 1:
                    System.exit(0);
                    break;
                default:
                    System.exit(0);
                    break;
            }
    }


Y con esto, ahora el juego se puede reiniciar tras cada partida, sin tener que crear nuevas instancias que se vayan acumulando en memoria.

Esto de la "comunicación entre clases" es algo que puede dar muchos quebraderos de cabeza, porque muchas veces necesitas que una única acción (pulsar el botón "SI") actúe sobre distintas clases y objetos.
Y aunque todas formen parte del mismo programa, no significa que estén comunicadas entre sí. De hecho, lo normal es que cada una tenga su ámbito propio, donde las otras clases no puedan meter mano.

Así que muchas veces habrá que abrir canales de comunicación mediante referencias entre unas y otras.

Por otra parte, esta comunicación se puede mejorar usando "patrones de diseño".
Es probable que hayas oído hablar del patrón "Modelo-Vista-Controlador", y si no tarde o temprano te hablarán de él.
Esto consiste en diseñar el programa de manera que unas clases se encarguen del Modelo del programa, es decir, los datos internos (contadores, evaluar resultados, etc,) y otras se encarguen de la Vista, lo que el usuario ve en pantalla (botones, diseño de interfaz, etc).

Entre estas, habría otra clase haciendo la función de Controlador. Esta clase tendría a todas las demás dentro de su ámbito y así puede encargarse de enviar los datos que una computa para que la otra los muestre, y actuar en todas ellas cuando sea necesario.

El programa que hemos hecho, en realidad, aplica este patrón pero no de la mejor forma.

La clase Combinación sería el Modelo.
Boton y PanelColores serían la Vista

Y la función del Controlador la llevan a medias entre MasterMind y Combinación, por eso hemos tenido que intercomunicarlas.

Lo ideal habría sido escribir el código de otro modo, para que solo MasterMind, o incluso otra clase creada específicamente para este propósito, fuera quien si encargase de "Controlar" si el juego ha terminado o no, de preguntar al usuario si quiere repetir o no, etc... dando y pidiendo datos a las clases del Modelo y de la Vista.


Pero bueno, todo esto lo comento para ampliar conocimientos.

Para ser nuestro primer MasterMind, yo creo que nos ha quedado muy bien je je..


EDITO:
Se me olvidó comentar un pequeño bug que surge tras todos estos cambios.
Al reiniciar partida, resulta que todos los campos se limpian pero luego en el campo de texto del útlimo panel donde hemos jugado, aparece el mensaje de "muertos y heridos".

Esto ocurre cuando se ha ganado, y es porque cuando ganamos, o sea cuando tenemos 4 muertos, el método evaluar() llama al JOptionPane para informar al usuario y si este quiere, se resetean los paneles para que siga jugando.

Pero el método evaluar()  no termina aquí, después de que todo se reinicie, el método continua con su algoritmo y retorna el String que contabiliza muertos y heridos.
Por eso tras el "reset" del juego, vuelve a aparecer esto en el campo de texto.

Para evitarlo, debemos poner fin al método evaluar() después de la llamada al JOptionPane, por ejemplo, pidiendo que retorne un valor null

Citar
        //Si encuentra 4 muertos, el juego está resuelto
        if (muertos == 4)
        {
            resuelto = true;
            JOptionPane.showMessageDialog(null, msjGanar, msjTitulo, JOptionPane.INFORMATION_MESSAGE);
            Respuesta();
            return null;
        }

Dejo el código completo en archivo adjunto (hay que estar logado en los foros para poder descargarlo).

564
Perdona si es una pregunta tonta, pero estoy buscando el significado de una instrucción que tienes puesta, pack(), en tu linea 29 de la clase MasterMind y no entiendo qué hace, por que sin ella no muestra ningún JFrame.

Edit: Vale buceando por el manual me he encontrado que el pack() lo que hace realmente es encargarse del diseño del marco para adaptarse, en vez de que use setSize o setBounds, sería correcta esta definición?
Gracias de antemano por vuestro tiempo siempre

Sí, pack() lo que hace es calcular el tamaño del JFrame, es decir, la ventana de la aplicación, basándose en el resto de componentes que este ha de contener: paneles, campos de texto, botones...
Lo hará de forma que todos esos componentes puedan cumplir su preferredSize.

A los componentes Swing podemos aplicarles un tamaño con setSize() y/o un tamaño preferido con setPreferredSize()


Por lo general es mejor usar pack() y preferredSize, porque aplica de forma excelente la maquetación de la interfaz, según los componentes, el layout escogido y también según el sistema operativo y configuración gráfica del ordenador donde se ejecuta.

La única desventaja es que al no imponer unos tamaños fijos, el tamaño de la interfaz a veces se nos puede ir de madre.

Yo por ejemplo, tengo un monitor QHD que me da una resolución de escritorio de 2560x1440 pixels.

Y claro, una interfaz que en mi pantalla se ve bien, que ni siquiera llega a los bordes del escritorio, si luego le paso mi aplicación otra persona con una pantalla de menor resolución como FullHD (que son más comunes), resulta que a esa persona se le ve enorme, incluso se sale de los bordes.

Pero bueno, eso son detalles que ahora no importan, lo importante ahora es aprender a programa y familiarizarse con Swing

565
pero no se como comparar un vector con el otro, paso el código pero sigo indagando

En mis mensajes anteriores expliqué cómo lo hice yo.

Me pareció lógico buscar primero "muertos", es decir, comparar las mismas posiciones de ambos vectores. Si contienen el mismo valor, contabilizamos un "muerto".
Esto lo podemos hacer con un único bucle, y usar el mismo índice para ambos vectores.

Luego, tocaría buscar "heridos". Esta vez si necesitaríamos dos bucles anidados, pues cada elemento del vector de valores, se ha de comparar con todos los elementos del vector "solucion".

Para hacer las comparaciones correctamente, cuando unas posiciones que han sido comparados han dado lugar a un "muerto" o un "herido", ya no deben volver a consultarse en las siguientes iteraciones de los bucles.
Así que esas posiciones han de marcarse de alguna forma para saber si debemos consultarlas o no.

En mi caso, en lugar de usar el tipo int para los vectores, use la clase Integer, que a efectos prácticos es lo mismo, pero al ser una clase puedo dar valores "null" a esas posiciones que quiero ignorar.

Si usas int, no puedes darle valor null... pero hay alternativas, como por ejemplo darles como valor -1 para "marcar" esas posiciones que no queremos volver a consultar.

Esto plantea otro problema, si damos valores null, o -1, o lo que sea... a los elementos del vector, estaríamos alterando su contenido.
En el caso del vector de "valores" no tiene importancia, porque cada vez que el usuario pulse el botón "Comprobar" se volverá a generar con nuevos valores, así que no importa si los alteramos cuando queramos "marcar" posiciones.

Pero en el caso del vector "solucion" si que sería un desastre, este vector una vez generados sus valores, no deberían alterarse a lo largo del juego.
Por eso, en mi caso, cada vez que el usuario pulsa el botón "Comprobar", hago una copia de ese vector y trabajo con la copia. De este modo no importa si modifico sus valores, siempre tendré el vector original intacto para la próxima vez que el usuario quiera comprobar.

566
Muy bien  ;)

Citar
Voy a ponerme ahora a generar numeros en un vector de 4 posiciones, sería lo correcto?

Sí, al usar vectores, luego es más cómodo recorrer con bucles esos números para hacer comparaciones.
Si cada número lo tenemos en una variable propia, no podremos usar bucles y el código para hacer comparaciones será más complejo.

Ánimo, y sigue intentando sacar tu propio código.

Puede que al leer mis mensajes, sea notable que exponga las ideas tan claras, y el código se vea sencillo y funcional.

Pero esto no es producto de un don divino, je je.., esto es después de mucho tiempo de indagar, probar, equivocarme, meterme en "laberintos" de lógica que no me llevaban a ninguna parte....
Yo he escrito códigos, que si existiera una policía de la programación, me habrían condenado a la silla eléctrica ja ja

Me he quedado atascado cientos de veces y dejado muchísimos programas sin completar porque ya no sabía como componer el desastre que estaba haciendo y era mejor dejarlo y empezar de nuevo.

Pero esos desastres siempre me han servido para aprender y sobre todo, para divertirme.

Sigue compartiendo lo que vayas logrando.
Un saludo.

567
Generar combinación secreta y evaluar...

Para esto yo crearía una nueva clase.

Generar la combinación es sencillo, generar 4 int aleatorios entre 1 y 6, y guardarlos en un array.

Para evaluar si han habido "muertos" y/o "heridos" según las reglas de Mastermind..., no se cuál puede ser la forma más óptima.

Yo he decidido trabajar en este caso con arrays de clase Integer en lugar de tipo primitivo int, porque con Integer puedo dar valores null a los elementos del array.
¿Y para que quiero poder dar valores null?

Pues porque cuando vaya a comparar "colores", si al comparar dos posiciones de los dos arrays (el de la combinación y el de la selección del usuario) se produce un "muerto" o un "herido", dichas posiciones no deben volver a consultarse mientras sigo evaluando los arrays.
Necesito marcar esas posiciones de algún modo para que no se vuelvan a consultar mientras dura esta evaluación.
Y una forma puede ser darles valores null.

Esto implica que no puedo trabajar directamente sobre el array de combinación secreta, pues destruiría la combinación al evaluar.
Así que cada vez que evalúe, haré una copia de la combinación y trabajaré sobre esta copia.

Así el método que se encarga de evaluar, recibirá un array con la selección del usuario, comparará con la copia de la combinación secreta, contabilizará posibles "muertos" y "heridos".. y por último retornará un String con el resultado.

Para contabilizar "muertos" y "heridos"..., primero buscaré "muertos", es decir, recorreré ambos arrays a ver si en la misma posición, coinciden colores.

Luego buscaré "heridos" en las posiciones que no hayan sido nulleadas (que no hayan generado "muertos").
Los heridos son colores escogidos que sí constan en la combinación, pero no en la misma posición.



Esta clase, también puede ser interesante que contabilice los intentos (máximo 10) y con un boolean controlar si se ha resuelto o no la combinación, es decir, si en algún momento se contabilizan 4 "muertos".

Esta podría ser la clase:
Código: [Seleccionar]
public class Combinacion {

private int[] combi;
public int intentos;
public boolean resuelto;

public Combinacion() {
combi = new int[4];
generaCombi();
intentos = 0;
resuelto = false;
}

public void generaCombi() {
Random azar = new Random();
for (int i = 0; i < combi.length; i++)
combi[i] = azar.nextInt(6) + 1;
}

public String evaluar(Integer[] colores) {
int muertos = 0;
int heridos = 0;

Integer[] copia = new Integer[4];
for (int i = 0; i < 4; i++)
copia[i] = combi[i];

//Busco muertos
for (int i = 0; i < 4; i++)
if (colores[i] == copia[i]) {
//Mismo color y misma posicion
muertos++;
//Nuleo posiciones, ya no deben consultarse más.
colores[i] = null;
copia[i] = null;
}

//Si hay 4 muertos, el juego está resuelto
if (muertos == 4)
resuelto = true;
else {
//Busco heridos, habrá que obviar posibles valores null
for (int i = 0; i < 4; i++) {
if (colores[i] != null)//Posición consultable
for (int j = 0; j < 4; j++) {
if (copia[j] != null)//Posición consultable
if (colores[i] == copia[j]) {
heridos++;
//Posiciones nulleadas
colores[i] = null;
copia[j] = null;
}
}
}
}

//Contabilizo intento
intentos++;

//Retorno resultado
String resultado = muertos==1?"1 Muerto - ":muertos + " Muertos - ";
resultado += heridos==1?"1 Herido":heridos + " Heridos";

return resultado; 
}
}

Y para que cada "panel de colores" sea capaz de evaluarse por sí mismo de forma autosuficiente, voy a cambiar su constructor y añadir como atributo una referencia al objeto Combinación que será instanciado en la clase principal JFrame.

Y modificaré el ActionListener de su botón "Comprobar" para que muestre en el campo de texto el resultado que devuelve el objeto Combinación.
Además haré que deshabilite los botones de colores y el mismo botón "Comprobar".
Pues una vez el usuario elija comprobar un panel de colores, no puede tener ocasión de volver a cambiarlo y volver a comprobar.

Citar
public class PanelColores extends JPanel{
   
   private Boton[] botones;
   JButton btComprobar;
   JTextField jtResultado;
   private Combinacion combinacion;
   
   public PanelColores(Combinacion combi) {
      
      add(new PanelBotones());
      add(new PanelComprobar());
      add(new PanelResultado());
      setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createEmptyBorder(5, 20, 5, 20),
            BorderFactory.createBevelBorder(BevelBorder.RAISED)));
      combinacion = combi;
   }
   
   private class PanelBotones extends JPanel {
      
      public PanelBotones() {
         //Inicializamos array de botones y añadimos
         botones = new Boton[4];
         for (int i = 0; i < botones.length; i++) {
            botones = new Boton(1);
            add(botones);
         }
         setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
      }
   }
   
   private class PanelComprobar extends JPanel {
      
      public PanelComprobar() {
         btComprobar = new JButton("Comprobar");
         btComprobar.setFont(new Font("Verdana", Font.BOLD, 14));
         btComprobar.addActionListener(new AccionComprobar());
         add(btComprobar);
         setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
      }
   }
   
   private class PanelResultado extends JPanel {
      
      public PanelResultado() {
         jtResultado = new JTextField(14);
         jtResultado.setEditable(false);
         jtResultado.setBackground(Color.WHITE);
         jtResultado.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
         jtResultado.setFont(new Font("Verdana", Font.BOLD, 14));
         jtResultado.setFocusable(false);
         jtResultado.setHorizontalAlignment(JTextField.CENTER);
         add(jtResultado);
         setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
      }
   }
   
   private class AccionComprobar implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         //Botones de este panel quedan inhabilitados
         botonesActivos(false);
         
         //Creamos array con los valores de los botones
         Integer[] valores = new Integer[4];
         for (int i = 0; i < 4; i++)
            valores = botones.getValor();
         
         //Evaluamos combinación y mostramos resultado en campo de texto
         jtResultado.setText(combinacion.evaluar(valores));

         
      }
   }
   
   public void botonesActivos(boolean activos) {
      btComprobar.setEnabled(activos);
      for (int i = 0; i < botones.length; i++)
         botones.setEnabled(activos);
   }

}

Y por último, en la clase JFrame instancio el objeto Combinación y lo paso al constructor de los paneles de colores.
Citar
public class MasterMind extends JFrame implements ActionListener{
   
   private Combinacion combinacion;
   
   public MasterMind() {
      
      combinacion = new Combinacion();
      
      JPanel panelesBotones = new JPanel();
      panelesBotones.setLayout(new BoxLayout(panelesBotones, BoxLayout.Y_AXIS));
      for (int i = 0; i < 10; i++)
         panelesBotones.add(new PanelColores(combinacion));
      add(panelesBotones);
      
      
      setTitle("MasterMind");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      pack();
      setLocationRelativeTo(null);
      setVisible(true);
   }

Si ahora lo ejecuto, tengo un juego funcional. He comenzado a evaluar desde abajo hacia arriba, y he acertado por los pelos en el último panel  ::)



Sin embargo, faltaría añadir más cositas, como mensajes de victoria/derrota o que el juego se reinicie para seguir jugando con una nueva combinación.

568
Yo voy a ir proponiendo mi código.
Tú puedes ir desarrollando el tuyo, basándote en el mío o como quieras.
Estaría genial que también lo compartieras por aquí.

Y ojalá más gente se animase a compartir también sus versiones para poder tener distintos puntos de vista y fórmulas de resolver un mismo ejercicio.

Como dije antes, para mi el siguiente paso lógico es crear un panel que tenga los 4 botones de colores, el botón "Comprobar" y un campo de texto para informar de resultados.

De momento, el resultado del que informará es de los valores seleccionados en los botones.
Por lo tanto, le pondré un ActionListener que al pulsar el botón "Comprobar", recupere los valores de cada botón, los junte en un array, y lo muestro en el campo de texto.
Este ActionListener es simplemente para "testeo", luego probablemente lo eliminaré.

Código: [Seleccionar]
public class PanelColores extends JPanel{

private Boton[] botones;
JButton btComprobar;
JTextField jtResultado;

public PanelColores() {

add(new PanelBotones());
add(new PanelComprobar());
add(new PanelResultado());
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(20, 10, 20, 10),
BorderFactory.createBevelBorder(BevelBorder.RAISED)));
}

private class PanelBotones extends JPanel {

public PanelBotones() {
//Inicializamos array de botones y añadimos
botones = new Boton[4];
for (int i = 0; i < botones.length; i++) {
botones[i] = new Boton(1);
add(botones[i]);
}
setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 15));
}
}

private class PanelComprobar extends JPanel {

public PanelComprobar() {
btComprobar = new JButton("Comprobar");
btComprobar.setFont(new Font("Verdana", Font.BOLD, 14));
btComprobar.addActionListener(new AccionComprobar());
add(btComprobar);
setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 15));
}
}

private class PanelResultado extends JPanel {

public PanelResultado() {
jtResultado = new JTextField(12);
jtResultado.setEditable(false);
jtResultado.setBackground(Color.WHITE);
jtResultado.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
jtResultado.setFont(new Font("Verdana", Font.BOLD, 14));
jtResultado.setFocusable(false);
jtResultado.setHorizontalAlignment(JTextField.CENTER);
add(jtResultado);
setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 15));
}
}

private class AccionComprobar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//Creamos array con los valores de los botones
int[] valores = new int[4];
for (int i = 0; i < 4; i++)
valores[i] = botones[i].getValor();
//Lo imprimo en el campo de texto
jtResultado.setText(Arrays.toString(valores));
}
}
}

Si ahora en el JFrame, muestro este panel:

Citar
public class MasterMind extends JFrame{
   
   public MasterMind() {
      
      JPanel prueba = new JPanel();
      prueba.add(new PanelColores());
      add(prueba);
      
      
      setTitle("MasterMind");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      pack();
      setLocationRelativeTo(null);
      setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {

         @Override
         public void run() {
            new MasterMind();   
         }
      });
   }
}

En pantalla veo modelado el concepto que tenía en mente:


A este panel le he puesto un borde compuesto, para que quede biselado y con unos píxeles de separación, ya que la idea es añadir diez de estos paneles a la interfaz, apilados unos sobre otros, y con esos bordes queda más elegante.

Citar
   public MasterMind() {
      
      JPanel panelesBotones = new JPanel();
      panelesBotones.setLayout(new BoxLayout(panelesBotones, BoxLayout.Y_AXIS));
      for (int i = 0; i < 10; i++)
         panelesBotones.add(new PanelColores());
      add(panelesBotones);

      
      
      setTitle("MasterMind");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      pack();
      setLocationRelativeTo(null);
      setVisible(true);
   }
Aunque lo he probado y me queda enorme xD, así que tengo que reducir píxeles de separación.

Pero bueno, al margen de eso, ya tengo una interfaz prácticamente completada:




Ahora ya habría que hacer lo de generar una combinación secreta y evaluar de verdad los aciertos del usuario.

A continuación mi código actual.

Clase Boton.java

Código: [Seleccionar]
package mastermind;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.border.BevelBorder;

@SuppressWarnings("serial")
public class Boton extends JButton implements ActionListener{

private int valor;

public Boton(int valor) {
this.valor = valor;
setPreferredSize(new Dimension(50, 50));
setFocusPainted(false);
cambiarColor();
addActionListener(this);
setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
}

public int getValor() {
return valor;
}

public void ciclarValor() {
if (valor == 6)
valor = 1; //Comienza de nuevo en 1
else
valor++;
cambiarColor();
}

public void cambiarColor() {
switch (valor) {
case 1:
setBackground(Color.RED);
break;
case 2:
setBackground(Color.BLUE);
break;
case 3:
setBackground(Color.GREEN);
break;
case 4:
setBackground(Color.YELLOW);
break;
case 5:
setBackground(Color.ORANGE);
break;
case 6:
setBackground(Color.WHITE);
}
}

@Override
public void actionPerformed(ActionEvent e) {
ciclarValor();
}

}


Clase MasterMind.java

Código: [Seleccionar]
package mastermind;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class MasterMind extends JFrame{

public MasterMind() {

JPanel panelesBotones = new JPanel();
panelesBotones.setLayout(new BoxLayout(panelesBotones, BoxLayout.Y_AXIS));
for (int i = 0; i < 10; i++)
panelesBotones.add(new PanelColores());
add(panelesBotones);


setTitle("MasterMind");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new MasterMind();
}
});
}
}


Clase PanelColores.java

Código: [Seleccionar]
package mastermind;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;

@SuppressWarnings("serial")
public class PanelColores extends JPanel{

private Boton[] botones;
JButton btComprobar;
JTextField jtResultado;

public PanelColores() {

add(new PanelBotones());
add(new PanelComprobar());
add(new PanelResultado());
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(5, 20, 5, 20),
BorderFactory.createBevelBorder(BevelBorder.RAISED)));
}

private class PanelBotones extends JPanel {

public PanelBotones() {
//Inicializamos array de botones y añadimos
botones = new Boton[4];
for (int i = 0; i < botones.length; i++) {
botones[i] = new Boton(1);
add(botones[i]);
}
setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
}
}

private class PanelComprobar extends JPanel {

public PanelComprobar() {
btComprobar = new JButton("Comprobar");
btComprobar.setFont(new Font("Verdana", Font.BOLD, 14));
btComprobar.addActionListener(new AccionComprobar());
add(btComprobar);
setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
}
}

private class PanelResultado extends JPanel {

public PanelResultado() {
jtResultado = new JTextField(12);
jtResultado.setEditable(false);
jtResultado.setBackground(Color.WHITE);
jtResultado.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
jtResultado.setFont(new Font("Verdana", Font.BOLD, 14));
jtResultado.setFocusable(false);
jtResultado.setHorizontalAlignment(JTextField.CENTER);
add(jtResultado);
setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
}
}

private class AccionComprobar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//Creamos array con los valores de los botones
int[] valores = new int[4];
for (int i = 0; i < 4; i++)
valores[i] = botones[i].getValor();
//Lo imprimo en el campo de texto
jtResultado.setText(Arrays.toString(valores));
}
}
}

569
Hola.
La verdad es que, ahora mismo, no se exactamente como resolverlo.

Pero estas cosas hay que empezar paso a paso, poco a poco. Nunca pensando en "el todo", porque "el todo" es mucho pensar... (parece una reflexión filosófica  ;D) y es entonces cuando nos venimos abajo  :-\

Hay que pensar en cosas pequeñas, en las partes que vamos a necesitar para conseguir "ese todo".

Por ejemplo, parece que vamos a necesitar unos botoncitos cuadrados, que alteren su color, según su valor entre 1 y 6.

Por la interfaz parece que el usuario al hacer click en esos botones decidirá su color (y por tanto su valor)

Pues comienza por eso.
Por crear una clase a partir de un JButton, que tenga un atributo int que admitirá valores entre 1 y 6.
Y según ese valor, se decidirá su color.

Así que tendrá que tener unos métodos para poder cambiar el valor del int, y cambiar el color del botón.

Y un ActionListener para que todo eso ocurra cuando el usuario lo clickee.

Intenta crear tú una clase que cumpla esto.

En cualquier caso, yo te propongo este código escrito por mí.

Clase Boton
Código: [Seleccionar]
public class Boton extends JButton implements ActionListener{

private int valor;

public Boton(int valor) {
this.valor = valor;
setPreferredSize(new Dimension(50, 50));
setFocusPainted(false);
cambiarColor();
addActionListener(this);
}

public int getValor() {
return valor;
}

public void ciclarValor() {
if (valor == 6)
valor = 1; //Comienza de nuevo en 1
else
valor++;
cambiarColor();
}

public void cambiarColor() {
switch (valor) {
case 1:
setBackground(Color.RED);
break;
case 2:
setBackground(Color.BLUE);
break;
case 3:
setBackground(Color.GREEN);
break;
case 4:
setBackground(Color.YELLOW);
break;
case 5:
setBackground(Color.ORANGE);
break;
case 6:
setBackground(Color.WHITE);
}
}

@Override
public void actionPerformed(ActionEvent e) {
ciclarValor();
}

}

Y esta es la clase JFrame donde ir creando el juego.
De momento, solo voy a poner el botón para comprobar si funciona, su aspecto, etc...

Código: [Seleccionar]
public class MasterMind extends JFrame{

public MasterMind() {

JPanel prueba = new JPanel();
prueba.add(new Boton(1));
add(prueba);


setTitle("MasterMind");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 300);
setLocationRelativeTo(null);
setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new MasterMind();
}
});
}
}

Y efectivamente, tengo un botón cuadrado que al hacerle click, va ciclando su valor y su color.


Pues ya tenemos un comienzo. Un primer ladrillo sobre el que seguir construyendo "el todo".

¿Siguiente paso?
Pues si volvemos a fijarnos en la interfaz... parece que podríamos usar varios paneles, apilados verticalmente, y cada uno compuesto de 4 botones de colores, un botón comprobar y un campo de texto que informe de los aciertos



Pues creo que este sería mi siguiente paso, modelar una clase JPanel con esos componentes.
De momento al principio no será capaz de informar de aciertos, porque aún no se ha implementado lo de generar la combinación aleatoria.
Pero para comprobar su funcionamiento, podemos hacer que cuando se pulse el botón "Comprobar", informe de los valores elegidos en los 4 botones.
Ya luego se le dará la funcionalidad correcta.

Yo seguiría por ese camino...

570
CONTINUACIÓN CÓDIGO COMPLETO

Código de la clase Evento.java

Código: [Seleccionar]
package actividadesYeventos;

public class Evento {

private String nombre;private String fecha;private String organizador;private String facultad;private String tema;//Salones de Actividades
private Actividad[] salones;public Evento() {nombre = ""; fecha = ""; organizador = ""; facultad = ""; tema = ""; salones = new Actividad[0]; //Contructor por defecto implica tener 0 salones.
}

public Evento(String nombreEven, String fechaEven, String organizaEven,
String facultadEven, String temaEven, int numSalones) {nombre = nombreEven; fecha = fechaEven; organizador = organizaEven; facultad = facultadEven; tema = temaEven; salones = new Actividad[numSalones]; //Al construir un evento, nos dirán cuantos salones tendrá
}

public String getNombre() {return nombre;}

public void setNombre(String nombreEven) {nombre = nombreEven;}

public String getFecha() {return fecha;}

public void setFecha(String fechaEven) {fecha = fechaEven;}

public String getOrganizador() {return organizador;}

public void setOrganizador(String organizaEven) {organizador = organizaEven;}

public String getFacultad() {return facultad;}

public void setFacultad(String facultadEven) {facultad = facultadEven;}

public String getTema() {return tema;}

public void setTema(String temaEven) {tema = temaEven;}

public void setNumSalones(int numSalones) {salones = new Actividad[numSalones];}

public void mostrarProgramacion() {//Es posible que no hayan salones asignados.
if (salones.length == 0)
System.out.println("\nEste EVENTO no tiene salones de ACTIVIDADES asignados"); else { /*
* Sí hay salones asignados, pero puede que aun no hayan actividades.
* Si TODAS las posiciones del array de Actividad tienen valor null,
* es que no hay actividades programadas.
*/
boolean hayActividades = false;//Si encontramos al menos 1 actividad, pasará a true
for (int i = 0; i < salones.length; i++) { if (salones[i] != null) { hayActividades = true; //Sí que hay actividades programadas
System.out.println("\nNº de Salón: " + i); System.out.println(salones[i]);//Mostramos datos de la Actividad
}
}
/*
* Terminado el bucle FOR, si la variable hayActividades
* conserva valor FALSE, es que no hay actividades
* programadas en este Evento y lo indicamos en pantalla.
*/
if (!hayActividades)
System.out.println("\nAún no se han programado ACTIVIDADES para este EVENTO");
}
}

/*
* Construye un String con los indices del arreglo
* que están libres y pueden recibir una Actividad.
* Si no hay ninguno libre, el String retornado estará vacío.
*/
public String getSalonesDisponibles() {String disponibles = ""; /*
* Recorremos los "salones", aquellos con valor null
* significa que están libres, así que recogemos su número
* para mostrarselo al usuario
*/
for (int i = 0; i < salones.length; i++)
if (salones[i] == null)
disponibles += "[" + i + "] ";
return disponibles;}

/*
* Recibe una Actividad y un número de salón donde programarla.
* Si en esta posición del arreglo (el salón) ya existe una Actividad
* o no existe dicha posición, se informará en pantalla.
*/
public void programarActividad(Actividad act, int salon) {try { if (salones[salon] == null) { //Salón disponible
salones[salon] = act; System.out.println("\nLa ACTIVIDAD ha sido programada."); }
else //Salon no tiene valor null, ya está ocupado por otro actividad
System.out.println("\nEl salón seleccionado ya tiene una ACTIVIDAD programada."); } catch(IndexOutOfBoundsException ex) { //Nos han dado un número de salón que no existe
System.out.println("\nNo existe el salón: " + salon); }
}

/*
* Busca la Actividad programada con más participantes y la retorna.
* Si no hubieran Actividades en este Evento, se retornará valor null.
*/
public Actividad getActividadMasParticipantes() {/*
* Buscaremos Actividades en los "salones" y guardaremos su cantidad de participantes
* para poder comparar con las siguientes y determinar cuál tiene
* MAYOR número de participantes.
*
* Para ello, iniciamos una variable con el valor int más BAJO posible
* y tener un valor inicial con el que poder comparar, buscando valores MAYORES
*/
int maxParticipantes = Integer.MIN_VALUE; //Para este caso, en realidad habría bastado con iniciar a 0

//Aquí guardaremos la actividad de MAYOR participacion
Actividad mayor = null;
for (Actividad activ: salones) { if (activ != null) //Solo consultamos salones que tengan Actividad programada
if (activ.getParticipantes() > maxParticipantes) { //Esta Actividad tiene MAS participantes que la anterior consultada
maxParticipantes = activ.getParticipantes(); //Actualizamos cantidad mayor de participantes
mayor = activ; //Guardamos la Actividad que, por ahora, tiene record de participantes
}
}

return mayor; //Retornamos la Actividad con más participantes
}

/*
* Busca la Actividad programada con menos participantes y la retorna.
* Si no hubieran Actividades en este Evento, se retornará valor null.
*/
public Actividad getActividadMenosParticipantes() {/*
* Buscaremos Actividades en los "salones" y guardaremos su cantidad de participantes
* para poder comparar con las siguientes y determinar cuál tiene
* MENOR número de participantes.
*
* Para ello, iniciamos una variable con el valor int más ALTO posible
* y tener un valor inicial con el que poder comparar, buscando valores MENORES
*/
int minParticipantes = Integer.MAX_VALUE;
//Aquí guardaremos la actividad de MENOR participacion
Actividad menor = null;
for (Actividad activ: salones) { if (activ != null) //Solo consultamos salones que tengan Actividad programada
if (activ.getParticipantes() < minParticipantes) { //Esta Actividad tiene MENOS participantes que la anterior consultada
minParticipantes = activ.getParticipantes(); menor = activ; }
}

return menor; //Retornamos la Actividad con más participantes
}

/*
* Retorna la suma total de participantes
* de todas las Actividades de este Evento.
*/
public int totalParticipantes() {int sumaParticipantes = 0;
//Recorremos arreglo de Actividades, y sumamos sus participantes
for (Actividad activ: salones)
if (activ != null)
sumaParticipantes += activ.getParticipantes();
return sumaParticipantes;}

/*
* Retorna el array de Actividades al completo.
*/
public Actividad[] getSalones() {return salones;}

/*
* Retorna una lista de las Actividades que expone
* el expositor especificado por parámetros.
*/
public String actividadesExpositor(String expositor) {String actividades = "";
for (Actividad activ: salones)
if (activ != null) //Si el salon tiene una Actividad...
if (activ.getExpositor().equals(expositor))//Y su Expositor coincide con el que consultan..
actividades += "- " + activ.getNombre() + "\n"; //Listamos el nombre de la Actividad

return actividades;}

}


Código de la clase MenuEventos.java

Código: [Seleccionar]
package actividadesYeventos;

import java.util.ArrayList;
import java.util.Scanner;

public class MenuEventos {

//Aquí se almacenarán los Eventos
private static ArrayList<Evento> eventos = new ArrayList<Evento>();//Objeto Scanner para leer datos por teclado
private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {crearEventosPorDefecto(); //Invocamos método que nos proporciona dos eventos.

String opcion = "";//Variable para recoger opcion del usuario

do { System.out.println("\n\t\tMENU EVENTOS"); System.out.println("\t\t---- -------\n"); System.out.println("[1] - Crear nuevo EVENTO"); System.out.println("[2] - Crear nueva ACTIVIDAD"); System.out.println("[3] - Mostrar ACTIVIDAD con mayor número de participantes"); System.out.println("[4] - Mostrar ACTIVIDAD con menor número de participantes"); System.out.println("[5] - Mostrar total participantes de un EVENTO"); System.out.println("[6] - Mostrar ACTIVIDADES ordenadas de mayor a menor número de participantes"); System.out.println("[7] - Consultar ACTIVIDADES de un expositor"); System.out.println("[8] - Mostrar programación de un EVENTO"); System.out.println("\n[0] - SALIR del programa"); System.out.print("\nEscoja opción: "); opcion = teclado.nextLine(); //Evaluamos opcion escogida
switch(opcion) { case "0":
System.out.println("\n\t\t--FIN DE PROGRAMA--"); break; case "1":
crearEvento(); break; case "2":
crearActividad(); break; case "3":
mostrarActividadMayor(); break; case "4":
mostrarActividadMenor(); break; case "5":
mostrarTotalParticipantesEvento(); break; case "6":
mostrarActividadesMayorMenor(); break; case "7":
consultarActividadesExpositor(); break; case "8":
mostrarActividadesEvento(); break; default:
System.out.println("\nOpción no válida..."); }
pausa(); } while(!opcion.equals("0"));}

/*
* Sencillo método que pausa la ejecución del programa
* hasta que el usuario pulse ENTER/INTRO
*/
private static void pausa() {System.out.println("\nPulse ENTER para seguir...\n"); teclado.nextLine();}

/*
* Crearemos dos eventos via código para que el
* programa comience con algunos datos con los
* que trabajar
*/
private static void crearEventosPorDefecto() {/*
* Recordamos que un evento tiene los atributos:
* nombre, fecha, organizador, facultad que organiza,
* temática y salones disponibles para actividades
*/
Evento tecnotic = new Evento("Tecnotic", "03/02/2021", "Ismael Clemente",
"MIT Club of Spain", "IA aplicada en operaciones bursátiles", 5); Evento softhard = new Evento("Softhard", "14/03/2021", "ParqueSoft",
"Universidad Antonio Jose Camacho", "Software Libre en Seguridad Informática", 3); //Además, les vamos a proporcionar algunas Actividades
tecnotic.programarActividad(new Actividad("Computación neuronal", "Kenzo Hirai", "09:30", 45), 0); tecnotic.programarActividad(new Actividad("CPU cuántica", "Santiago Gutierrez", "12:00", 32), 3); softhard.programarActividad(new Actividad("Kernel UNIX", "Michael John", "13:15", 25), 1); softhard.programarActividad(new Actividad("Heurística por hardware", "Teresa Almeida", "12:00", 32), 2); //Eventos creados, los agregamos al ArrayList que los almacena
eventos.add(tecnotic); eventos.add(softhard);}

/*
* Muestra al usuario los Eventos disponibles para que
* elija uno y saldrá en pantalla sus Actividades programadas,
* si es que las tiene.
*/
private static void mostrarActividadesEvento() {System.out.println("\nEVENTOS disponibles:"); for (int i = 0; i < eventos.size(); i++) { System.out.println(i + " - " + eventos.get(i).getNombre()); }
System.out.print("\nSeleccione nº de EVENTO: "); int num = Integer.parseInt(teclado.nextLine());
/*
* Con try catch, podemos capturar la posible
* excepción que podría ocurrir si el usuario
* nos da una posición que no existe en el ArrayList
* y así obraremos en consecuencia.
*/
try { eventos.get(num).mostrarProgramacion(); } catch(IndexOutOfBoundsException ex) { System.out.println("Selección equivocada..."); }
}

/*
* Pide los datos necesarios para crear
* un Evento y lo agrega al ArrayList
*/
private static void crearEvento() {//Pedimos datos del evento
System.out.println("\nNombre del EVENTO: "); String nombre = teclado.nextLine(); System.out.println("Fecha: "); String fecha = teclado.nextLine(); System.out.println("Organizador: "); String organizador = teclado.nextLine(); System.out.println("Facultad que organiza: "); String facultad = teclado.nextLine(); System.out.println("Temática: "); String tema = teclado.nextLine(); System.out.println("Cantidad salones asignados: "); int salones = Integer.parseInt(teclado.nextLine()); //Creamos un evento nuevo y añadimos al ArrayList
eventos.add(new Evento(nombre, fecha, organizador, facultad, tema, salones));}

/*
* Permite al usuario crear una Actividad y escoger
* un Evento y salón disponible para programarla.
*/
private static void crearActividad() {//Pedimos datos de la actividad
System.out.println("Nombre de la ACTIVIDAD: "); String nombre = teclado.nextLine(); System.out.println("Expositor: "); String expositor = teclado.nextLine(); System.out.println("Hora: "); String hora = teclado.nextLine(); System.out.println("Cantidad de Participantes: "); int participantes = Integer.parseInt(teclado.nextLine());
//Creamos la Actividad
Actividad nuevaActiv = new Actividad(nombre, expositor, hora, participantes);
//Tenemos Actividad, preguntamos en que Evento lo vamos a programar
System.out.println("\nEVENTOS disponibles:"); for (int i = 0; i < eventos.size(); i++) { System.out.println(i + " - " + eventos.get(i).getNombre()); }
System.out.print("\nSeleccione nº de EVENTO: "); int num = Integer.parseInt(teclado.nextLine());
try { Evento evento = eventos.get(num); String salones = evento.getSalonesDisponibles(); if (salones.isEmpty())//Evento ha retornado un String vacío, no hay salones libres
System.out.println("Este EVENTO está completo. No hay salones disponibles."); else { System.out.println("Salones disponibles: " + salones); System.out.print("Elija salón donde programar la ACTIVIDAD: "); int salon = Integer.parseInt(teclado.nextLine()); evento.programarActividad(nuevaActiv, salon);//Pasamos actividad y salon, Evento se encarga del resto
}
} catch(IndexOutOfBoundsException ex) {//Ha elegido un evento que no existe
System.out.println("Selección equivocada..."); }
}

private static void mostrarActividadMayor() {/*
* Recorreremos los Eventos, pidiéndole a cada uno
* que nos devuelva su Actividad con más participantes
* y de todas estas nos quedaremos con la mayor de todas.
*/

Actividad mayor = null; int maxParticipantes = Integer.MIN_VALUE; String eventoMayor = ""; //También guardaremos el nombre del Evento con Actividad mayor.

for (Evento event: eventos) { if (event.getActividadMasParticipantes() != null)
if (event.getActividadMasParticipantes().getParticipantes() > maxParticipantes) { mayor = event.getActividadMasParticipantes(); maxParticipantes = mayor.getParticipantes(); eventoMayor = event.getNombre(); }
}

/*
* Comprobamos si tenemos alguna Actividad como resultado
* y mostramos datos.
* Podríamos no tener ningún resultado, debido a que quizás
* aún no se han programado Actividades.
*/

if (mayor ==  null)
System.out.println("No hay ACTIVIDADES programadas en ningún EVENTO"); else { System.out.println("\nACTIVIDAD con más participantes"); System.out.println("- Nombre: " + mayor.getNombre()); System.out.println("- Participantes: " + maxParticipantes); System.out.println("- Evento: " + eventoMayor); }
}

private static void mostrarActividadMenor() {Actividad menor = null; int minParticipantes = Integer.MAX_VALUE; String eventoMenor = "";
for (Evento event: eventos) { if (event.getActividadMenosParticipantes() != null)
if (event.getActividadMenosParticipantes().getParticipantes() < minParticipantes) { menor = event.getActividadMenosParticipantes(); minParticipantes = menor.getParticipantes(); eventoMenor = event.getNombre(); }
}

if (menor ==  null)
System.out.println("No hay ACTIVIDADES programadas en ningún EVENTO"); else { System.out.println("\nACTIVIDAD con menos participantes"); System.out.println("- Nombre: " + menor.getNombre()); System.out.println("- Participantes: " + minParticipantes); System.out.println("- Evento: " + eventoMenor); }
}

private static void mostrarTotalParticipantesEvento() {System.out.println("\nEVENTOS disponibles:"); for (int i = 0; i < eventos.size(); i++) { System.out.println(i + " - " + eventos.get(i).getNombre()); }
System.out.print("\nSeleccione nº de EVENTO: "); int num = Integer.parseInt(teclado.nextLine());
try { System.out.println("Evento seleccionado: " + eventos.get(num).getNombre()); System.out.println("Total participantes: " + eventos.get(num).totalParticipantes()); } catch(IndexOutOfBoundsException ex) { System.out.println("Selección equivocada..."); }
}

private static void mostrarActividadesMayorMenor() {//Recopilaremos TODAS las Actividades programas en un único ArrayList
ArrayList<Actividad> actividades = new ArrayList<Actividad>();
/*
* Recorremos todos los Eventos y les pediremos sus Salones.
* De estos Salones, cogeremos las Actividades programadas
*/

for (Evento event: eventos) { Actividad[] salones = event.getSalones(); for (Actividad activ: salones)
if (activ != null) //Buscamos Salones que si tengan Actividades
actividades.add(activ); }

/*
* Ya hemos recorrido todos los Eventos y tenemos sus Actividades.
* Ahora hay que ordenar de mayor a menor.
* Pero ojo, puede que no hayamos encontrado Actividades,
* o que solo haya una y por tanto no hay nada que ordenar
*/

if (actividades.isEmpty())
System.out.println("No hay Actividades programadas en ningún Evento"); else if (actividades.size() == 1) { System.out.println("\nActividades disponibles: 1"); System.out.println(actividades.get(0)); }
else { System.out.println("\nActividades disponibles: " + actividades.size()); //Método Burbuja
for (int i = 0; i < actividades.size() - 1; i++) {
            for (int j = 0; j < actividades.size() - i - 1; j++) {
            //Si la actividad siguiente en el array, es MAYOR que la actual...
                if (actividades.get(j + 1).compareTo(actividades.get(j)) == 1) {
                //...entonces hay que intercambiar sus posiciones para ordenarlas
                    Actividad aux = actividades.get(j + 1);                    actividades.set(j + 1, actividades.get(j));                    actividades.set(j, aux);                }
            }
        }
//ArrayList ordenado de mayor a menor. Mostramos las Actividades en pantalla
for (Actividad activ: actividades)
System.out.println(activ); }

}

private static void consultarActividadesExpositor() {//Pedimos nombre del expositor
System.out.print("Nombre del Expositor: "); String expositor = teclado.nextLine();
boolean actividadesEncontradas = false; //Para controlar si se encontró alguna Actividad

//Consultamos los Eventos
for (Evento event: eventos) { String actividades = event.actividadesExpositor(expositor); if (!actividades.isEmpty()) { //El String retornado NO está vacío, se han encontrado Actividades
actividadesEncontradas = true; System.out.println("\nEVENTO: " + event.getNombre()); System.out.println("ACTIVIDADES donde expone:"); System.out.println(actividades); }
}
//Tras recorrer todos los eventos, si NO se han encontrado Actividades, informamos
if (!actividadesEncontradas)
System.out.println("\nNo se han encontrado ACTIVIDADES para el Expositor: "  + expositor);}
}


Saludos

571
Método de ordenación burbuja

Es un algoritmo para ordenar una colección de datos.

Por eso puse enlace de Wikipedia, que seguro explican mejor que yo.

Lo que hace es recorrer varias veces la colección de datos, comparando cada elemento con el siguiente para decidir si hay que intercambiar posiciones para dejarlo ordenado.

Esta imagen representa el proceso de ordenación:


El método de la Burbuja es algo que todo programador debe conocer, como mínimo saber que existe y para qué se usa.

Luego, como ya dije, en Java las clases Arrays, ArrayList, etc.. tienen un método que ordenan automáticamente las colecciones de datos, siempre que esos datos implementen la interfaz Comparable y se le haya escrito correctamente el método compareTo().
Pero el método de la Burbuja hay que conocerlo, y muy probablemente algún día te lo pidan en una prueba de examen.


Terminación del ejercicio

Última funcionalidad que queda por activar: Consultar las Actividades de un Expositor.

Habrá que pedir al usuario un nombre de Expositor y recorrer los EVentos en busca de Actividades donde el EXpositor coincida con el nombre que nos da el usuario.

Para esto lo primero será proporcionar a la clase Evento un método que reciba el nombre de Expositor y consulte sus "salones" a ver si hay Actividades para ese Expositor.
Las Actividades que encuentre (pueden ser más de una) lo que haremos será recoger sus nombres y retornarlas en un String.

A Evento, le escribimos este método:
Código: [Seleccionar]
/*
* Retorna una lista de las Actividades que expone
* el expositor especificado por parámetros.
*/
public String actividadesExpositor(String expositor) {

String actividades = "";

for (Actividad activ: salones)
if (activ != null) //Si el salon tiene una Actividad...
if (activ.getExpositor().equals(expositor))//Y su Expositor coincide con el que consultan..
actividades += "- " + activ.getNombre() + "\n"; //Listamos el nombre de la Actividad

return actividades;
}

Luego, en MenuEventos, le escribimos el método donde pedimos nombre al usuario y recorremos los Eventos en busca de Actividades.
Si se encuentran, se irá mostrando el String que retornan con las listas de Actividades donde ese Expositor va a exponer.

Si no se encuentra ninguna, cosa que vamos a controlar con un boolean, informaremos al usuario.

Código: [Seleccionar]
private static void consultarActividadesExpositor() {
//Pedimos nombre del expositor
System.out.print("Nombre del Expositor: ");
String expositor = teclado.nextLine();

boolean actividadesEncontradas = false; //Para controlar si se encontró alguna Actividad

//Consultamos los Eventos
for (Evento event: eventos) {
String actividades = event.actividadesExpositor(expositor);
if (!actividades.isEmpty()) { //El String retornado NO está vacío, se han encontrado Actividades
actividadesEncontradas = true;
System.out.println("\nEVENTO: " + event.getNombre());
System.out.println("ACTIVIDADES donde expone:");
System.out.println(actividades);
}
}
//Tras recorrer todos los eventos, si NO se han encontrado Actividades, informamos
if (!actividadesEncontradas)
System.out.println("\nNo se han encontrado ACTIVIDADES para el Expositor: "  + expositor);
}

Y en el SWITCH activamos este método, y listo programa terminado.

Citar
         switch(opcion) {
         case "0":
            System.out.println("\n\t\t--FIN DE PROGRAMA--");
            break;
         case "1":
            crearEvento();
            break;
         case "2":
            crearActividad();
            break;
         case "3":
            mostrarActividadMayor();
            break;
         case "4":
            mostrarActividadMenor();
            break;
         case "5":
            mostrarTotalParticipantesEvento();
            break;
         case "6":
            mostrarActividadesMayorMenor();
            break;
         case "7":
            consultarActividadesExpositor();
            break;
         case "8":
            mostrarActividadesEvento();
            break;
         default:
            System.out.println("\nOpción no válida...");
         }

Espero que haya servido para que se entienda la lógica de programación que se ha seguido, para conocer un poco mejor el lenguaje Java, etc...

También importante darse cuenta de que no es necesario resolver un programa al 100% de una tacada.

Se puede ir paso a paso, objetivo por objetivo.

Cualquier duda, por favor, preguntadla aquí en el foro.

Un saludo.



CÓDIGO COMPLETO


Código de la clase Actividad.java

Código: [Seleccionar]
package actividadesYeventos;

public class Actividad implements Comparable<Actividad>{

private String nombre;
private String expositor;//Persona que expone
private String hora;
private int participantes;

/*
* Constructor sin parámetros. Con esto nos aseguramos de que al construir
* un objeto Actividad, no tendremos atributos con valor null
*/
public Actividad() {
nombre = "";
expositor = "";
hora = "";
participantes = 0;
}

/*
* Constructor con parámetros. El objeto se construye recibiendo los valores
* que vamos a asignar a los atributos.
*/
public Actividad(String nombreActiv, String nombreExpos, String horaActiv, int numParticipan) {
nombre = nombreActiv;
expositor = nombreExpos;
hora = horaActiv;
participantes = numParticipan;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombreActiv) {nombre = nombreActiv;}

public String getExpositor() {return expositor;}

public void setExpositor(String nombreExpos) {expositor = nombreExpos;}

public String getHora() {return hora;}

public void setHora(String horaActiv) {hora = horaActiv;}

public int getParticipantes() {return participantes;}

public void setParticipantes(int numParticipan) {participantes = numParticipan;}

@Override
public String toString() {return "\n\t\t----------------\nNombre de ACTIVIDAD: " + nombre
+ "\nExpositor: " + expositor
+ "\nHora: " +  hora + "\nParticipantes: " + participantes
+ "\n\t\t----------------\n";}

/*
* Este método recibe "otra" Actividad por parámetro para compararse
* con "esta" Actividad.
* La comparación es para determinar una relación ordinal, es decir,
* quien es "menor" y quien es "mayor".
* La Actividad con MENOS participantes se considerará menor que otra
* con MÁS participantes.
*
* Si el objeto recibido tiene valor null, se producirá una excepción.
*/
@Override
public int compareTo(Actividad otraActividad) {//Comparamos sus participantes, para ver quien es menor o mayor, o si son iguales
if (participantes == otraActividad.getParticipantes())
return 0; //Mismo número de participantes, son iguales
else if (participantes < otraActividad.getParticipantes())
return -1; //Esta Actividad es "menor" que la Actividad recibida por parámetro.
else
return 1; //Esta Actividad es "mayor".
}

}

572
6ª opcion.
Ordenar de mayor a menor.

La cosa consistiría en recorrer todas las Actividades, de todos los Eventos, y ordenarlas según su atributo número de participantes.
Para ordenarlas, previamente habría que juntarlas todas en una misma colección.
Se podría usar un arreglo normal, pero como no sabemos cuántas Actividades vamos a encontrar, pues no sabemos a que tamaño deberíamos inicializarlo.

Para resolver este inconveniente tenemos dos opciones:
- Añadir más código extra para primero sumar las Actividades existentes y así saber que tamaño necesitamos para el arreglo. Esto además supone más ciclos de computación.

- Usar un ArrayList, que como ya explicamos, no tiene tamaño fijo y podemos ir metiéndole Actividades según las vamos encontrando, sin tener que contar primero cuántas hay.

Yo prefiero la segunda opción.
Así, crearemos un ArrayList con todas las Actividades, las ordenaremos, y las mostraremos en pantalla.

¿Y como ordenamos de mayor a menor?
Habrá que pedirle a cada actividad que nos indique sus participantes, comparar las participantes de una con las demás e intercambiar las posiciones entre ellas hasta conseguir que primero estén las de mayor participación y al final las de menos.

Ya puestos, podemos aprovechar y aprender algo nuevo usando la interfaz Comparable
Podemos pedirle a la clase Actividad que implemente esta interfaz, y esto nos añadirá un método que vamos a sobreescribir para que "enseñarle" como una Actividad ha de compararse con otra para decidir cuál es mayor y cuál menor.

Para ello, nos vamos a la clase Actividad y le pedimos que implemente esta interfaz:

Citar
package actividadesYeventos;

public class Actividad implements Comparable<Actividad>{
   
   private String nombre;
   private String expositor;//Persona que expone
   private String hora;
   private int participantes;

Con esa línea en negrita le estamos diciendo que implemente la interfaz Comparable, y que solo ha de aceptar objetos que pertenezcan a la clase Actividad para poder hacer la comparación.
No tiene sentido que acepte compararse con un String, o con un Integer, o con un Evento... ni con absolutamente nada que no sea una Actividad.

Al pedirle que implemente esa interfaz, el compilador/IDE nos va a EXIGIR que a esta clase le añadamos un método llamado compareTo().
Es dentro de este método donde vamos a poner el código para decidir cómo se han de comparar los objetos Actividad para decidir quien es mayor o menor.
Nosotros decidimos como hacerlo, podríamos decirle que se ordenara según el tamaño de su nombre, o por orden alfabético, o según la hora en la que la Actividad esta programada...

En este caso, nos interesa que se ordenen según la cantidad de participantes
Código: [Seleccionar]
/*
* Este método recibe "otra" Actividad por parámetro para compararse
* con "esta" Actividad.
* La comparación es para determinar una relación ordinal, es decir,
* quien es "menor" y quien es "mayor".
* La Actividad con MENOS participantes se considerará menor que otra
* con MÁS participantes.
*
* Si el objeto recibido tiene valor null, se producirá una excepción.
*/
@Override
public int compareTo(Actividad otraActividad) {

//Comparamos sus participantes, para ver quien es menor o mayor, o si son iguales
if (participantes == otraActividad.getParticipantes())
return 0; //Mismo número de participantes, son iguales
else if (participantes < otraActividad.getParticipantes())
return -1; //Esta Actividad es "menor" que la Actividad recibida por parámetro.
else
return 1; //Esta Actividad es "mayor".
}

Este método decide la comparación retornando un int.
Si el int es 0, es que los objetos son "iguales", es decir ninguno es mayor o menor.
Si retorna un valor negativo, es que ESTE objeto, es menor que el OTRO objeto que ha recibido por parámetros para compararse.

Si ESTE objeto es mayor, entonces retorna un valor positivo.

Java usa esta forma de compararse con la intención de que sea igual para todas las clases. Así luego podemos pedirle a las colecciones de datos que se ordenen ellas solas.

Es decir, el ArrayList de Actividades que vamos a construir después, si queremos ya podemos decirle con la instrucción sort() que el solito ordene sus elementos. Porque sus elementos ya tienen el método compareTo() y ya saben compararse ellos mismos para indicar quien es menor y quien es mayor.

Sin embargo, para este ejercicio cuyo propósito es aprender cosas nuevas, no vamos a ser tan cómodos de usar el sort() y usaremos un algoritmo de ordenación para hacer nosotros la tarea de ordenar.

Para esto, nos vamos a la clase MenuEventos para crear el método que mostrarás las Actividades ordenadas.
Este método, va a realizar estos pasos:

- Crear un ArrayList para objetos de la clase Actividad
- Recorrer cada Evento, y de cada Evento, recorrer sus "salones" buscando Actividades programadas que añadiremos a ese ArrayList.
- Ordenar el ArrayList de mayor a menor.
- Mostrar las Actividades en pantalla.

Aquí tenemos un problemita, para recorrer los "salones" de un Evento, necesitamos que el Evento nos de acceso directo a ellos. Y ahora mismo nuestra clase Evento no tiene ningún método que nos de ese acceso.
Así que primero, a la clase Evento vamos a darle este método para que nos retorne su arreglo de Actividades (sus "salones") y así tener libre acceso a ellos:
Código: [Seleccionar]
/*
* Retorna el array de Actividades al completo.
*/
public Actividad[] getSalones() {
return salones;
}

Con esto solucionamos el problemita para cumplir el segundo paso.
Ya sí podemos añadir este método a la clase MenuEventos

Código: [Seleccionar]
private static void mostrarActividadesMayorMenor() {

//Recopilaremos TODAS las Actividades programas en un único ArrayList
ArrayList<Actividad> actividades = new ArrayList<Actividad>();

/*
* Recorremos todos los Eventos y les pediremos sus Salones.
* De estos Salones, cogeremos las Actividades programadas
*/

for (Evento event: eventos) {
Actividad[] salones = event.getSalones();
for (Actividad activ: salones)
if (activ != null) //Buscamos Salones que si tengan Actividades
actividades.add(activ);
}

/*
* Ya hemos recorrido todos los Eventos y tenemos sus Actividades.
* Ahora hay que ordenar de mayor a menor.
* Pero ojo, puede que no hayamos encontrado Actividades,
* o que solo haya una y por tanto no hay nada que ordenar
*/

if (actividades.isEmpty())
System.out.println("No hay Actividades programadas en ningún Evento");
else if (actividades.size() == 1) {
System.out.println("\nActividades disponibles: 1");
System.out.println(actividades.get(0));
}
else {
System.out.println("\nActividades disponibles: " + actividades.size());
//Método Burbuja
for (int i = 0; i < actividades.size() - 1; i++) {
            for (int j = 0; j < actividades.size() - i - 1; j++) {
            //Si la actividad siguiente en el array, es MAYOR que la actual...
                if (actividades.get(j + 1).compareTo(actividades.get(j)) == 1) {
                //...entonces hay que intercambiar sus posiciones para ordenarlas
                    Actividad aux = actividades.get(j + 1);
                    actividades.set(j + 1, actividades.get(j));
                    actividades.set(j, aux);
                }
            }
        }
//ArrayList ordenado de mayor a menor. Mostramos las Actividades en pantalla
for (Actividad activ: actividades)
System.out.println(activ);
}

}

Para ordenar estamos usando el algoritmo de la Burbuja, un sistema muy usado en programación, de los primeros que se enseñan. No es el más óptimo pero si sencillo de usar y entender. Aunque puede que al principio tengas que ver más ejemplos para entender como funciona.

Y con esto, ya solo queda llamar a este método dentro del SWITCH

Citar
         switch(opcion) {
         case "0":
            System.out.println("\n\t\t--FIN DE PROGRAMA--");
            break;
         case "1":
            crearEvento();
            break;
         case "2":
            crearActividad();
            break;
         case "3":
            mostrarActividadMayor();
            break;
         case "4":
            mostrarActividadMenor();
            break;
         case "5":
            mostrarTotalParticipantesEvento();
            break;
         case "6":
            mostrarActividadesMayorMenor();
            break;
         case "7":
            System.out.println("\nEn construccion...");
            break;

Y ya podemos ver todas las Actividades ordenadas de mayor a menor.

Fíjate que si quisiéramos cambiar el orden y mostrarlas de menor a mayor, nos bastaría con pedirle al algoritmo de la burbuja que haga el cambio cuando compareTo() devuelva -1

Citar
         //Método Burbuja
         for (int i = 0; i < actividades.size() - 1; i++) {
               for (int j = 0; j < actividades.size() - i - 1; j++) {
                  //Si la actividad siguiente en el array, es MENOR que la actual...
                   if (actividades.get(j + 1).compareTo(actividades.get(j)) == -1) {
                      //...entonces hay que intercambiar sus posiciones para ordenarlas
                       Actividad aux = actividades.get(j + 1);
                       actividades.set(j + 1, actividades.get(j));
                       actividades.set(j, aux);
                   }
               }
           }

573
Aún tengo tiempo de añadir otra funcionalidad del menú.
La de mostrar el total de participantes de un Evento, que es algo muy sencillo.

Para esta opción lo que haremos será pedir al usuario que elija un Evento y le mostraremos cuantos participantes hay en total.
Es decir, sumaremos los participantes de todas las Actividades de ese Evento seleccionado.

De nuevo, lo mejor es "enseñarle" a la clase Evento que sea capaz de darnos este dato.
Así que le añadimos este método:
Código: [Seleccionar]
/*
* Retorna la suma total de participantes
* de todas las Actividades de este Evento.
*/
public int totalParticipantes() {

int sumaParticipantes = 0;

//Recorremos arreglo de Actividades, y sumamos sus participantes
for (Actividad activ: salones)
if (activ != null)
sumaParticipantes += activ.getParticipantes();

return sumaParticipantes;
}

Y en la clase principal MenuEventos, añadimos este método para que el usuario elija un Evento y podamos mostrarle este dato:

Código: [Seleccionar]
private static void mostrarTotalParticipantesEvento() {
System.out.println("\nEVENTOS disponibles:");
for (int i = 0; i < eventos.size(); i++) {
System.out.println(i + " - " + eventos.get(i).getNombre());
}
System.out.print("\nSeleccione nº de EVENTO: ");
int num = Integer.parseInt(teclado.nextLine());

try {
System.out.println("Evento seleccionado: " + eventos.get(num).getNombre());
System.out.println("Total participantes: " + eventos.get(num).totalParticipantes());
} catch(IndexOutOfBoundsException ex) {
System.out.println("Selección equivocada...");
}
}

Y en el SWITCH llamamos a este nuevo método, y listo..

Citar
         switch(opcion) {
         case "0":
            System.out.println("\n\t\t--FIN DE PROGRAMA--");
            break;
         case "1":
            crearEvento();
            break;
         case "2":
            crearActividad();
            break;
         case "3":
            mostrarActividadMayor();
            break;
         case "4":
            mostrarActividadMenor();
            break;
         case "5":
            mostrarTotalParticipantesEvento();
            break;

574
Vamos a añadir dos nuevas funcionalidades que son muy parecidas, las de mostrar la Actividad con mayor número de participantes y la de menor.

Pero primero, para que sea más cómodo probar estas funciones, creo que conviene añadir por código algunas Actividades a los dos Eventos que nos pedían crear en el enunciado.
Si no, cada vez que ejecutamos el programa y queramos probar las nuevas funciones, tendríamos que teclear nuevas Actividades siempre.
Si creamos ya algunas por código, ya comenzaremos el programa con datos listos para trabajar.

Así que podemos modificar el método donde creábamos los dos Eventos, y les añadimos dos Actividades a cada uno:

Citar
   private static void crearEventosPorDefecto() {
      
      /*
       * Recordamos que un evento tiene los atributos:
       * nombre, fecha, organizador, facultad que organiza,
       * temática y salones disponibles para actividades
       */
      Evento tecnotic = new Evento("Tecnotic", "03/02/2021", "Ismael Clemente",
            "MIT Club of Spain", "IA aplicada en operaciones bursátiles", 5);
      Evento softhard = new Evento("Softhard", "14/03/2021", "ParqueSoft",
            "Universidad Antonio Jose Camacho", "Software Libre en Seguridad Informática", 3);
      //Además, les vamos a proporcionar algunas Actividades
      tecnotic.programarActividad(new Actividad("Computación neuronal", "Kenzo Hirai", "09:30", 45), 0);
      tecnotic.programarActividad(new Actividad("CPU cuántica", "Santiago Gutierrez", "12:00", 32), 3);
      softhard.programarActividad(new Actividad("Kernel UNIX", "Michael John", "13:15", 25), 1);
      softhard.programarActividad(new Actividad("Heurística por hardware", "Teresa Almeida", "12:00", 32), 2);

      //Eventos creados, los agregamos al ArrayList que los almacena
      eventos.add(tecnotic);
      eventos.add(softhard);
   }


Bien, para obtener la Actividad con mayor número de participantes, tenemos que recorrer los Eventos, y por cada Evento, recorrer sus Actividades buscando la Actividad con el mayor número de participantes.

Para facilitar esto, podemos programarle a la clase Evento un método que se encargue de recorrer por su cuenta sus Actividades y retorne la Actividad con más participantes.

A Evento, le añadimos este método:
Código: [Seleccionar]
/*
* Busca la Actividad programada con más participantes y la retorna.
* Si no hubieran Actividades en este Evento, se retornará valor null.
*/
public Actividad getActividadMasParticipantes() {

/*
* Buscaremos Actividades en los "salones" y guardaremos su cantidad de participantes
* para poder comparar con las siguientes y determinar cuál tiene
* MAYOR número de participantes.
*
* Para ello, iniciamos una variable con el valor int más BAJO posible
* y tener un valor inicial con el que poder comparar, buscando valores MAYORES
*/
int maxParticipantes = Integer.MIN_VALUE; //Para este caso, en realidad habría bastado con iniciar a 0

//Aquí guardaremos la actividad de MAYOR participacion
Actividad mayor = null;

for (Actividad activ: salones) {
if (activ != null) //Solo consultamos salones que tengan Actividad programada
if (activ.getParticipantes() > maxParticipantes) {
//Esta Actividad tiene MAS participantes que la anterior consultada
maxParticipantes = activ.getParticipantes(); //Actualizamos cantidad mayor de participantes
mayor = activ; //Guardamos la Actividad que, por ahora, tiene record de participantes
}
}

return mayor; //Retornamos la Actividad con más participantes
}

Y también este otro, que es prácticamente lo mismo, pero para encontrar la Actividad con menor participación.

Código: [Seleccionar]
/*
* Busca la Actividad programada con menos participantes y la retorna.
* Si no hubieran Actividades en este Evento, se retornará valor null.
*/
public Actividad getActividadMenosParticipantes() {

/*
* Buscaremos Actividades en los "salones" y guardaremos su cantidad de participantes
* para poder comparar con las siguientes y determinar cuál tiene
* MENOR número de participantes.
*
* Para ello, iniciamos una variable con el valor int más ALTO posible
* y tener un valor inicial con el que poder comparar, buscando valores MENORES
*/
int minParticipantes = Integer.MAX_VALUE;

//Aquí guardaremos la actividad de MENOR participacion
Actividad menor = null;

for (Actividad activ: salones) {
if (activ != null) //Solo consultamos salones que tengan Actividad programada
if (activ.getParticipantes() < minParticipantes) {
//Esta Actividad tiene MENOS participantes que la anterior consultada
minParticipantes = activ.getParticipantes();
menor = activ;
}
}

return menor; //Retornamos la Actividad con más participantes
}


Con estos dos métodos, ya podemos pedirle a un Evento que nos retorne su Actividad con mayor o menor número de participantes.

Ahora volvemos a la clase principal MenuEventos para añadir los métodos que, de TODOS los Eventos, encuentre la mayor o menos Actividad de todas.

El código será muy similar a los que hemos escrito, pero ahora recorremos Eventos y además guardaremos el nombre del Evento que posee la Actividad mayor o menor.
Así podemos darle al usuario información más completa.

Así que añadimos estos dos métodos a MenuEventos:
Código: [Seleccionar]
private static void mostrarActividadMayor() {
/*
* Recorreremos los Eventos, pidiéndole a cada uno
* que nos devuelva su Actividad con más participantes
* y de todas estas nos quedaremos con la mayor de todas.
*/

Actividad mayor = null;
int maxParticipantes = Integer.MIN_VALUE;
String eventoMayor = ""; //También guardaremos el nombre del Evento con Actividad mayor.

for (Evento event: eventos) {
if (event.getActividadMasParticipantes() != null)
if (event.getActividadMasParticipantes().getParticipantes() > maxParticipantes) {
mayor = event.getActividadMasParticipantes();
maxParticipantes = mayor.getParticipantes();
eventoMayor = event.getNombre();
}
}

/*
* Comprobamos si tenemos alguna Actividad como resultado
* y mostramos datos.
* Podríamos no tener ningún resultado, debido a que quizás
* aún no se han programado Actividades.
*/

if (mayor ==  null)
System.out.println("No hay ACTIVIDADES programadas en ningún EVENTO");
else {
System.out.println("\nACTIVIDAD con más participantes");
System.out.println("- Nombre: " + mayor.getNombre());
System.out.println("- Participantes: " + maxParticipantes);
System.out.println("- Evento: " + eventoMayor);
}
}

private static void mostrarActividadMenor() {

Actividad menor = null;
int minParticipantes = Integer.MAX_VALUE;
String eventoMenor = "";

for (Evento event: eventos) {
if (event.getActividadMenosParticipantes() != null)
if (event.getActividadMenosParticipantes().getParticipantes() < minParticipantes) {
menor = event.getActividadMenosParticipantes();
minParticipantes = menor.getParticipantes();
eventoMenor = event.getNombre();
}
}

if (menor ==  null)
System.out.println("No hay ACTIVIDADES programadas en ningún EVENTO");
else {
System.out.println("\nACTIVIDAD con menos participantes");
System.out.println("- Nombre: " + menor.getNombre());
System.out.println("- Participantes: " + minParticipantes);
System.out.println("- Evento: " + eventoMenor);
}
}

Y en el SWITCH, llamamos a estos métodos en los cases correspondientes:
Citar
         switch(opcion) {
         case "0":
            System.out.println("\n\t\t--FIN DE PROGRAMA--");
            break;
         case "1":
            crearEvento();
            break;
         case "2":
            crearActividad();
            break;
         case "3":
            mostrarActividadMayor();
            break;
         case "4":
            mostrarActividadMenor();
            break;

Y ya podemos buscar las Actividades con más y menos participantes, de todos los Eventos existentes.

575
Adjunto en este mensaje el código de los tres archivos .java tal y como los tengo ahora.
(Debajo de este texto).

Hoy domingo trabajo  :-\ , luego más tarde a ver si puedo seguir avanzando con el programa.

Mientras tanto, revisa bien el código por si te surgen nuevas dudas.


Código de la clase Actividad

Código: [Seleccionar]
package actividadesYeventos;

public class Actividad {

private String nombre;
private String expositor;//Persona que expone
private String hora;
private int participantes;

/*
* Constructor sin parámetros.
* Con esto nos aseguramos de que al construir
* un objeto Actividad, no tendremos atributos
* con valor null
*/
public Actividad() {
nombre = "";
expositor = "";
hora = "";
participantes = 0;
}

/*
* Constructor con parámetros.
* El objeto se construye recibiendo los valores
* que vamos a asignar a los atributos.
*/
public Actividad(String nombreActiv, String nombreExpos, String horaActiv, int numParticipan) {
nombre = nombreActiv;
expositor = nombreExpos;
hora = horaActiv;
participantes = numParticipan;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombreActiv) {
nombre = nombreActiv;
}

public String getExpositor() {
return expositor;
}

public void setExpositor(String nombreExpos) {
expositor = nombreExpos;
}

public String getHora() {
return hora;
}

public void setHora(String horaActiv) {
hora = horaActiv;
}

public int getParticipantes() {
return participantes;
}

public void setParticipantes(int numParticipan) {
participantes = numParticipan;
}

@Override
public String toString() {
return "\n\t\t----------------\nNombre de ACTIVIDAD: " + nombre
+ "\nExpositor: " + expositor
+ "\nHora: " +  hora + "\nParticipantes: " + participantes
+ "\n\t\t----------------\n";
}
}


Código de la clase Evento

Código: [Seleccionar]
package actividadesYeventos;

public class Evento {

private String nombre;
private String fecha;
private String organizador;
private String facultad;
private String tema;

//Salones de Actividades
private Actividad[] salones;

public Evento() {
nombre = "";
fecha = "";
organizador = "";
facultad = "";
tema = "";
salones = new Actividad[0]; //Contructor por defecto implica tener 0 salones.
}

public Evento(String nombreEven, String fechaEven, String organizaEven,
String facultadEven, String temaEven, int numSalones) {
nombre = nombreEven;
fecha = fechaEven;
organizador = organizaEven;
facultad = facultadEven;
tema = temaEven;
salones = new Actividad[numSalones]; //Al construir un evento, nos dirán cuantos salones tendrá
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombreEven) {
nombre = nombreEven;
}

public String getFecha() {
return fecha;
}

public void setFecha(String fechaEven) {
fecha = fechaEven;
}

public String getOrganizador() {
return organizador;
}

public void setOrganizador(String organizaEven) {
organizador = organizaEven;
}

public String getFacultad() {
return facultad;
}

public void setFacultad(String facultadEven) {
facultad = facultadEven;
}

public String getTema() {
return tema;
}

public void setTema(String temaEven) {
tema = temaEven;
}

public void setNumSalones(int numSalones) {
salones = new Actividad[numSalones];
}

public void mostrarProgramacion() {

//Es posible que no hayan salones asignados.
if (salones.length == 0)
System.out.println("\nEste EVENTO no tiene salones de ACTIVIDADES asignados");
else {
/*
* Sí hay salones asignados, pero puede que aun no hayan actividades.
* Si TODAS las posiciones del array de Actividad tienen valor null,
* es que no hay actividades programadas.
*/
boolean hayActividades = false;//Si encontramos al menos 1 actividad, pasará a true
for (int i = 0; i < salones.length; i++) {
if (salones[i] != null) {
hayActividades = true; //Sí que hay actividades programadas
System.out.println("\nNº de Salón: " + i);
System.out.println(salones[i]);//Mostramos datos de la Actividad
}
}
/*
* Terminado el bucle FOR, si la variable hayActividades
* conserva valor FALSE, es que no hay actividades
* programadas en este Evento y lo indicamos en pantalla.
*/
if (!hayActividades)
System.out.println("\nAún no se han programado ACTIVIDADES para este EVENTO");
}
}

/*
* Construye un String con los indices del arreglo
* que están libres y pueden recibir una Actividad.
* Si no hay ninguno libre, el String retornado estará vacío.
*/
public String getSalonesDisponibles() {

String disponibles = "";
/*
* Recorremos los "salones", aquellos con valor null
* significa que están libres, así que recogemos su número
* para mostrarselo al usuario
*/
for (int i = 0; i < salones.length; i++)
if (salones[i] == null)
disponibles += "[" + i + "] ";

return disponibles;
}

/*
* Recibe una Actividad y un número de salón donde programarla.
* Si en esta posición del arreglo (el salón) ya existe una Actividad
* o no existe dicha posición, se informará en pantalla.
*/
public void programarActividad(Actividad act, int salon) {

try {
if (salones[salon] == null) { //Salón disponible
salones[salon] = act;
System.out.println("\nLa ACTIVIDAD ha sido programada.");
}
else //Salon no tiene valor null, ya está ocupado por otro actividad
System.out.println("\nEl salón seleccionado ya tiene una ACTIVIDAD programada.");
} catch(IndexOutOfBoundsException ex) { //Nos han dado un número de salón que no existe
System.out.println("\nNo existe el salón: " + salon);
}
}

}


Código de la clase MenuEventos

Código: [Seleccionar]
package actividadesYeventos;

import java.util.ArrayList;
import java.util.Scanner;

public class MenuEventos {

//Aquí se almacenarán los Eventos
private static ArrayList<Evento> eventos = new ArrayList<Evento>();
//Objeto Scanner para leer datos por teclado
private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {

crearEventosPorDefecto(); //Invocamos método que nos proporciona dos eventos.

String opcion = "";//Variable para recoger opcion del usuario

do {
System.out.println("\n\t\tMENU EVENTOS");
System.out.println("\t\t---- -------\n");
System.out.println("[1] - Crear nuevo EVENTO");
System.out.println("[2] - Crear nueva ACTIVIDAD");
System.out.println("[3] - Mostrar ACTIVIDAD con mayor número de participantes");
System.out.println("[4] - Mostrar ACTIVIDAD con menor número de participantes");
System.out.println("[5] - Mostrar total participantes de un EVENTO");
System.out.println("[6] - Mostrar ACTIVIDADES ordenadas de mayor a menos número de participantes");
System.out.println("[7] - Consultar ACTIVIDADES de un expositor");
System.out.println("[8] - Mostrar programación de un EVENTO");
System.out.println("\n[0] - SALIR del programa");
System.out.print("\nEscoja opción: ");
opcion = teclado.nextLine();
//Evaluamos opcion escogida
switch(opcion) {
case "0":
System.out.println("\n\t\t--FIN DE PROGRAMA--");
break;
case "1":
crearEvento();
break;
case "2":
crearActividad();
break;
case "3":
System.out.println("\nEn construccion...");
break;
case "4":
System.out.println("\nEn construccion...");
break;
case "5":
System.out.println("\nEn construccion...");
break;
case "6":
System.out.println("\nEn construccion...");
break;
case "7":
System.out.println("\nEn construccion...");
break;
case "8":
mostrarActividadesEvento();
break;
default:
System.out.println("\nOpción no válida...");
}
pausa();
} while(!opcion.equals("0"));
}

/*
* Sencillo método que pausa la ejecución del programa
* hasta que el usuario pulse ENTER/INTRO
*/
private static void pausa() {
System.out.println("\nPulse ENTER para seguir...\n");
teclado.nextLine();
}

/*
* Crearemos dos eventos via código para que el
* programa comience con algunos datos con los
* que trabajar
*/
private static void crearEventosPorDefecto() {

/*
* Recordamos que un evento tiene los atributos:
* nombre, fecha, organizador, facultad que organiza,
* temática y salones disponibles para actividades
*/
Evento tecnotic = new Evento("Tecnotic", "03/02/2021", "Ismael Clemente",
"MIT Club of Spain", "IA aplicada en operaciones bursátiles", 5);
Evento softhard = new Evento("Softhard", "14/03/2021", "ParqueSoft",
"Universidad Antonio Jose Camacho", "Software Libre en Seguridad Informática", 3);
//Eventos creados, los agregamos al ArrayList que los almacena
eventos.add(tecnotic);
eventos.add(softhard);
}

/*
* Muestra al usuario los Eventos disponibles para que
* elija uno y saldrá en pantalla sus Actividades programadas,
* si es que las tiene.
*/
private static void mostrarActividadesEvento() {
System.out.println("\nEVENTOS disponibles:");
for (int i = 0; i < eventos.size(); i++) {
System.out.println(i + " - " + eventos.get(i).getNombre());
}
System.out.print("\nSeleccione nº de EVENTO: ");
int num = Integer.parseInt(teclado.nextLine());

/*
* Con try catch, podemos capturar la posible
* excepción que podría ocurrir si el usuario
* nos da una posición que no existe en el ArrayList
* y así obraremos en consecuencia.
*/
try {
eventos.get(num).mostrarProgramacion();
} catch(IndexOutOfBoundsException ex) {
System.out.println("Selección equivocada...");
}
}

/*
* Pide los datos necesarios para crear
* un Evento y lo agrega al ArrayList
*/
private static void crearEvento() {
//Pedimos datos del evento
System.out.println("\nNombre del EVENTO: ");
String nombre = teclado.nextLine();
System.out.println("Fecha: ");
String fecha = teclado.nextLine();
System.out.println("Organizador: ");
String organizador = teclado.nextLine();
System.out.println("Facultad que organiza: ");
String facultad = teclado.nextLine();
System.out.println("Temática: ");
String tema = teclado.nextLine();
System.out.println("Cantidad salones asignados: ");
int salones = Integer.parseInt(teclado.nextLine());
//Creamos un evento nuevo y añadimos al ArrayList
eventos.add(new Evento(nombre, fecha, organizador, facultad, tema, salones));
}

/*
* Permite al usuario crear una Actividad y escoger
* un Evento y salón disponible para programarla.
*/
private static void crearActividad() {
//Pedimos datos de la actividad
System.out.println("Nombre de la ACTIVIDAD: ");
String nombre = teclado.nextLine();
System.out.println("Expositor: ");
String expositor = teclado.nextLine();
System.out.println("Hora: ");
String hora = teclado.nextLine();
System.out.println("Cantidad de Participantes: ");
int participantes = Integer.parseInt(teclado.nextLine());

//Creamos la Actividad
Actividad nuevaActiv = new Actividad(nombre, expositor, hora, participantes);

//Tenemos Actividad, preguntamos en que Evento lo vamos a programar
System.out.println("\nEVENTOS disponibles:");
for (int i = 0; i < eventos.size(); i++) {
System.out.println(i + " - " + eventos.get(i).getNombre());
}
System.out.print("\nSeleccione nº de EVENTO: ");
int num = Integer.parseInt(teclado.nextLine());

try {
Evento evento = eventos.get(num);
String salones = evento.getSalonesDisponibles();
if (salones.isEmpty())//Evento ha retornado un String vacío, no hay salones libres
System.out.println("Este EVENTO está completo. No hay salones disponibles.");
else {
System.out.println("Salones disponibles: " + salones);
System.out.print("Elija salón donde programar la ACTIVIDAD: ");
int salon = Integer.parseInt(teclado.nextLine());
evento.programarActividad(nuevaActiv, salon);//Pasamos actividad y salon, Evento se encarga del resto
}
} catch(IndexOutOfBoundsException ex) {//Ha elegido un evento que no existe
System.out.println("Selección equivocada...");
}
}
}

576
Podemos continuar añadiendo dos nuevas funcionalidades:
Añadir Eventos y Añadir Actividades (a un Evento)

Añadir Evento, la opción 1 del menú, es sencillo.
Solo hay que pedir por teclado los datos necesarios para construir un Evento.
Una vez los tenemos, añadimos al ArrayList el nuevo Evento.

A la clase MenuEventos, le añadimos este método:
Código: [Seleccionar]
/*
* Pide los datos necesarios para crear
* un Evento y lo agrega al ArrayList
*/
private static void crearEvento() {
//Pedimos datos del evento
System.out.println("\nNombre del EVENTO: ");
String nombre = teclado.nextLine();
System.out.println("Fecha: ");
String fecha = teclado.nextLine();
System.out.println("Organizador: ");
String organizador = teclado.nextLine();
System.out.println("Facultad que organiza: ");
String facultad = teclado.nextLine();
System.out.println("Temática: ");
String tema = teclado.nextLine();
System.out.println("Cantidad salones asignados: ");
int salones = Integer.parseInt(teclado.nextLine());
//Creamos un evento nuevo y añadimos al ArrayList
eventos.add(new Evento(nombre, fecha, organizador, facultad, tema, salones));
}

Y en el case 1 del SWITCH, invocamos este método:
Citar
         switch(opcion) {
         case "0":
            System.out.println("\n\t\t--FIN DE PROGRAMA--");
            break;
         case "1":
            crearEvento();
            break;
         case "2":

Ahora ya podemos crear más Eventos, a parte de los otros dos que el enunciado nos pedía hardcodear

Pero pasemos a algo más interesante, programar Actividades para un Evento.

Esta vez el proceso es un poco, solo un poco, más difícil.

Primero pediremos los datos necesarios para crear una Actividad.
Cuando la tengamos, le mostraremos al usuario los Eventos disponibles para que elija uno.
Cuando lo haya elegido, mostraremos en pantalla los "salones" que ese Evento tiene disponibles para que el usuario elija un salón

Así, ya podemos pedirle al Evento, que programe esa Actividad, en ese salón.

Para facilitar todo esto, vamos a modificar la clase Evento para añadirle dos nuevas funcionalidades.
Una va a ser que nos comunique que salones tiene disponibles. Podemos hacer por ejemplo que construya un String con los números de salones (posiciones del arreglo de Actividades) que tengan valor null, es decir, que todavía no tienen Actividades.
Si todos los salones están ocupados, retornará un String vacío.

A Evento, le añadimos este método:
Código: [Seleccionar]
/*
* Construye un String con los indices del arreglo
* que están libres y pueden recibir una Actividad.
* Si no hay ninguno libre, el String retornado estará vacío.
*/
public String getSalonesDisponibles() {

String disponibles = "";
/*
* Recorremos los "salones", aquellos con valor null
* significa que están libres, así que recogemos su número
* para mostrárselo al usuario
*/
for (int i = 0; i < salones.length; i++)
if (salones[i] == null) //Salón está libre
disponibles += "[" + i + "] ";

return disponibles;
}

La siguiente funcionalidad que necesitamos para Evento, es que reciba una Actividad y un número de salón, y agregue esa Actividad al arreglo.
Deberá gestionar las posibilidades de que el "salón" ya esté ocupado y también que nos hayan dado un número de salón que no existe.

Le añadimos este otro método:
Código: [Seleccionar]
/*
* Recibe una Actividad y un número de salón donde programarla.
* Si en esta posición del arreglo (el salón) ya existe una Actividad
* o no existe dicha posición, se informará en pantalla.
*/
public void programarActividad(Actividad act, int salon) {

try {
if (salones[salon] == null) { //Salón disponible
salones[salon] = act;
System.out.println("\nLa ACTIVIDAD ha sido programada.");
}
else //Salon no tiene valor null, ya está ocupado por otro actividad
System.out.println("\nEl salón seleccionado ya tiene una ACTIVIDAD programada.");
} catch(IndexOutOfBoundsException ex) { //Nos han dado un número de salón que no existe
System.out.println("\nNo existe el salón: " + salon);
}
}

Ahora Evento ya es capaz de informar de salones disponibles y también de añadir una Actividad en el salón indicado.
Volvemos a la clase MenuEventos para añadir un método que nos permita crear una Actividad y programarla en el Evento y salón escogidos por el usuario.

Código: [Seleccionar]
/*
* Permite al usuario crear una Actividad y escoger
* un Evento y salón disponible para programarla.
*/
private static void crearActividad() {
//Pedimos datos de la actividad
System.out.println("Nombre de la ACTIVIDAD: ");
String nombre = teclado.nextLine();
System.out.println("Expositor: ");
String expositor = teclado.nextLine();
System.out.println("Hora: ");
String hora = teclado.nextLine();
System.out.println("Cantidad de Participantes: ");
int participantes = Integer.parseInt(teclado.nextLine());

//Creamos la Actividad
Actividad nuevaActiv = new Actividad(nombre, expositor, hora, participantes);

//Tenemos Actividad, preguntamos en que Evento lo vamos a programar
System.out.println("\nEVENTOS disponibles:");
for (int i = 0; i < eventos.size(); i++) {
System.out.println(i + " - " + eventos.get(i).getNombre());
}
System.out.print("\nSeleccione nº de EVENTO: ");
int num = Integer.parseInt(teclado.nextLine());

try {
Evento evento = eventos.get(num);
String salones = evento.getSalonesDisponibles();
if (salones.isEmpty())//Evento ha retornado un String vacío, no hay salones libres
System.out.println("Este EVENTO está completo. No hay salones disponibles.");
else {
System.out.println("Salones disponibles: " + salones);
System.out.print("Elija salón donde programar la ACTIVIDAD: ");
int salon = Integer.parseInt(teclado.nextLine());
evento.programarActividad(nuevaActiv, salon);//Pasamos actividad y salon, Evento se encarga del resto
}
} catch(IndexOutOfBoundsException ex) {//Ha elegido un evento que no existe
System.out.println("Selección equivocada...");
}
}

Y por último, en el case 2 del SWITCH, llamamos a este método:
Citar
         switch(opcion) {
         case "0":
            System.out.println("\n\t\t--FIN DE PROGRAMA--");
            break;
         case "1":
            crearEvento();
            break;
         case "2":
            crearActividad();
            break;

Ahora ya podemos crear Eventos y Actividades.
Y ver las Actividades programadas.

En pantalla vemos algo así:

Citar
      MENU EVENTOS
      ---- -------

[1] - Crear nuevo EVENTO
[2] - Crear nueva ACTIVIDAD
[3] - Mostrar ACTIVIDAD con mayor número de participantes
[4] - Mostrar ACTIVIDAD con menor número de participantes
[5] - Mostrar total participantes de un EVENTO
[6] - Mostrar ACTIVIDADES ordenadas de mayor a menos número de participantes
[7] - Consultar ACTIVIDADES de un expositor
[8] - Mostrar programación de un EVENTO

[ 0] - SALIR del programa

Escoja opción: 1

Nombre del EVENTO:
Java
Fecha:
29/11/2020
Organizador:
Aprender A Programar
Facultad que organiza:
APR
Temática:
Código Java
Cantidad salones asignados:
5

Pulse ENTER para seguir...



      MENU EVENTOS
      ---- -------

[1] - Crear nuevo EVENTO
[2] - Crear nueva ACTIVIDAD
[3] - Mostrar ACTIVIDAD con mayor número de participantes
[4] - Mostrar ACTIVIDAD con menor número de participantes
[5] - Mostrar total participantes de un EVENTO
[6] - Mostrar ACTIVIDADES ordenadas de mayor a menos número de participantes
[7] - Consultar ACTIVIDADES de un expositor
[8] - Mostrar programación de un EVENTO

[ 0] - SALIR del programa

Escoja opción: 2
Nombre de la ACTIVIDAD:
Programación Orientada a Objetos
Expositor:
Kabuto
Hora:
03:00
Cantidad de Participantes:
26

EVENTOS disponibles:
0 - Tecnotic
1 - Softhard
2 - Java

Seleccione nº de EVENTO: 2
Salones disponibles: [ 0] [1] [2] [3] [4]
Elija salón donde programar la ACTIVIDAD: 2

La ACTIVIDAD ha sido programada.

Pulse ENTER para seguir...



      MENU EVENTOS
      ---- -------

[1] - Crear nuevo EVENTO
[2] - Crear nueva ACTIVIDAD
[3] - Mostrar ACTIVIDAD con mayor número de participantes
[4] - Mostrar ACTIVIDAD con menor número de participantes
[5] - Mostrar total participantes de un EVENTO
[6] - Mostrar ACTIVIDADES ordenadas de mayor a menos número de participantes
[7] - Consultar ACTIVIDADES de un expositor
[8] - Mostrar programación de un EVENTO

[ 0] - SALIR del programa

Escoja opción: 8

EVENTOS disponibles:
0 - Tecnotic
1 - Softhard
2 - Java

Seleccione nº de EVENTO: 2

Nº de Salón: 2

      ----------------
Nombre de ACTIVIDAD: Programación Orientada a Objetos
Expositor: Kabuto
Hora: 03:00
Participantes: 26
      ----------------


Pulse ENTER para seguir...

577
Sí.
Vamos a tener 3 clases: Actividad, Evento y MenuEventos.

Cada clase será un archivo .java separado.
Es decir, tu proyecto ha de tener tres archivos: Actividad.java, Evento.java y MenuEventos.java.

No se si estás usando algún IDE como NetBeans, Eclipse, etc... Pero la estructura del proyecto viene a ser igual en todos.

Estos tres archivos deberían estar dentro de lo que se llama un package, es decir dentro de un directorio.
Puedes llamarlo como quieras, yo lo he llamado actividadesYeventos

Este package estaría dentro de la carpeta src de tu proyecto.

Te muestro foto de la estructura de mi proyecto Java, que en mi caso se llama "Varios" porque tengo varios packages con distintos programas.



MenuEventos es la clase principal, la que tiene el método main() que pone en marcha el programa y además tendrá los métodos para hacer funcionar cada opción del menú, que iremos añadiendo poco a poco.

Según añadimos nuevas funcionalidades al programa, vamos a tener que ir modificando las tres clases para añadirles nuevos métodos que hagan posible esas funcionalidades.
El código de estas clases que puse al principio solo tenía lo básico, según avanzamos en el programa su código irá aumentando.

Ahora mismo, las clases deberían estar así.

Actividad

Código: [Seleccionar]
package actividadesYeventos;

public class Actividad {

private String nombre;
private String expositor;//Persona que expone
private String hora;
private int participantes;

/*
* Constructor sin parámetros.
* Con esto nos aseguramos de que al construir
* un objeto Actividad, no tendremos atributos
* con valor null
*/
public Actividad() {
nombre = "";
expositor = "";
hora = "";
participantes = 0;
}

/*
* Constructor con parámetros.
* El objeto se construye recibiendo los valores
* que vamos a asignar a los atributos.
*/
public Actividad(String nombreActiv, String nombreExpos, String horaActiv, int numParticipan) {
nombre = nombreActiv;
expositor = nombreExpos;
hora = horaActiv;
participantes = numParticipan;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombreActiv) {
nombre = nombreActiv;
}

public String getExpositor() {
return expositor;
}

public void setExpositor(String nombreExpos) {
expositor = nombreExpos;
}

public String getHora() {
return hora;
}

public void setHora(String horaActiv) {
hora = horaActiv;
}

public int getParticipantes() {
return participantes;
}

public void setParticipantes(int numParticipan) {
participantes = numParticipan;
}

@Override
public String toString() {
return "\n\t\t----------------\nNombre de ACTIVIDAD: " + nombre
+ "\nExpositor: " + expositor
+ "\nHora: " +  hora + "\nParticipantes: " + participantes
+ "\n\t\t----------------\n";
}
}

Evento
Código: [Seleccionar]
package actividadesYeventos;

public class Evento {

private String nombre;
private String fecha;
private String organizador;
private String facultad;
private String tema;

//Salones de Actividades
private Actividad[] salones;

public Evento() {
nombre = "";
fecha = "";
organizador = "";
facultad = "";
tema = "";
salones = new Actividad[0]; //Contructor por defecto implica tener 0 salones.
}

public Evento(String nombreEven, String fechaEven, String organizaEven,
String facultadEven, String temaEven, int numSalones) {
nombre = nombreEven;
fecha = fechaEven;
organizador = organizaEven;
facultad = facultadEven;
tema = temaEven;
salones = new Actividad[numSalones]; //Al construir un evento, nos dirán cuantos salones tendrá
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombreEven) {
nombre = nombreEven;
}

public String getFecha() {
return fecha;
}

public void setFecha(String fechaEven) {
fecha = fechaEven;
}

public String getOrganizador() {
return organizador;
}

public void setOrganizador(String organizaEven) {
organizador = organizaEven;
}

public String getFacultad() {
return facultad;
}

public void setFacultad(String facultadEven) {
facultad = facultadEven;
}

public String getTema() {
return tema;
}

public void setTema(String temaEven) {
tema = temaEven;
}

public void setNumSalones(int numSalones) {
salones = new Actividad[numSalones];
}

public void mostrarProgramacion() {

//Es posible que no hayan salones asignados.
if (salones.length == 0)
System.out.println("\nEste EVENTO no tiene salones de ACTIVIDADES asignados");
else {
/*
* Sí hay salones asignados, pero puede que aun no hayan actividades.
* Si TODAS las posiciones del array de Actividad tienen valor null,
* es que no hay actividades programadas.
*/
boolean hayActividades = false;//Si encontramos al menos 1 actividad, pasará a true
for (int i = 0; i < salones.length; i++) {
if (salones[i] != null) {
hayActividades = true; //Sí que hay actividades programadas
System.out.println("\nNº de Salón: " + i);
System.out.println(salones[i]);//Mostramos datos de la Actividad
}
}
/*
* Terminado el bucle FOR, si la variable hayActividades
* conserva valor FALSE, es que no hay actividades
* programadas en este Evento y lo indicamos en pantalla.
*/
if (!hayActividades)
System.out.println("\nAún no se han programado ACTIVIDADES para este EVENTO");
}
}

}

MenuEventos

Código: [Seleccionar]
package actividadesYeventos;

import java.util.ArrayList;
import java.util.Scanner;

public class MenuEventos {

//Aquí se almacenarán los Eventos
private static ArrayList<Evento> eventos = new ArrayList<Evento>();
//Objeto Scanner para leer datos por teclado
private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {

crearEventosPorDefecto(); //Invocamos método que nos proporciona dos eventos.

String opcion = "";//Variable para recoger opcion del usuario

do {
System.out.println("\n\t\tMENU EVENTOS");
System.out.println("\t\t---- -------\n");
System.out.println("[1] - Crear nuevo EVENTO");
System.out.println("[2] - Crear nueva ACTIVIDAD");
System.out.println("[3] - Mostrar ACTIVIDAD con mayor número de participantes");
System.out.println("[4] - Mostrar ACTIVIDAD con menor número de participantes");
System.out.println("[5] - Mostrar total participantes de un EVENTO");
System.out.println("[6] - Mostrar ACTIVIDADES ordenadas de mayor a menos número de participantes");
System.out.println("[7] - Consultar ACTIVIDADES de un expositor");
System.out.println("[8] - Mostrar programación de un EVENTO");
System.out.println("\n[0] - SALIR del programa");
System.out.print("\nEscoja opción: ");
opcion = teclado.nextLine();
//Evaluamos opcion escogida
switch(opcion) {
case "0":
System.out.println("\n\t\t--FIN DE PROGRAMA--");
break;
case "1":
System.out.println("\nEn construccion...");
break;
case "2":
System.out.println("\nEn construccion...");
break;
case "3":
System.out.println("\nEn construccion...");
break;
case "4":
System.out.println("\nEn construccion...");
break;
case "5":
System.out.println("\nEn construccion...");
break;
case "6":
System.out.println("\nEn construccion...");
break;
case "7":
System.out.println("\nEn construccion...");
break;
case "8":
mostrarActividadesEvento();
break;
default:
System.out.println("\nOpción no válida...");
}
pausa();
} while(!opcion.equals("0"));
}

/*
* Sencillo método que pausa la ejecución del programa
* hasta que el usuario pulse ENTER/INTRO
*/
private static void pausa() {
System.out.println("\nPulse ENTER para seguir...\n");
teclado.nextLine();
}

/*
* Crearemos dos eventos via código para que el
* programa comience con algunos datos con los
* que trabajar
*/
private static void crearEventosPorDefecto() {

/*
* Recordamos que un evento tiene los atributos:
* nombre, fecha, organizador, facultad que organiza,
* temática y salones disponibles para actividades
*/
Evento tecnotic = new Evento("Tecnotic", "03/02/2021", "Ismael Clemente",
"MIT Club of Spain", "IA aplicada en operaciones bursátiles", 5);
Evento softhard = new Evento("Softhard", "14/03/2021", "ParqueSoft",
"Universidad Antonio Jose Camacho", "Software Libre en Seguridad Informática", 3);
//Eventos creados, los agregamos al ArrayList que los almacena
eventos.add(tecnotic);
eventos.add(softhard);
}

/*
* Muestra al usuario los Eventos disponibles para que
* elija uno y saldrá en pantalla sus Actividades programadas,
* si es que las tiene.
*/
private static void mostrarActividadesEvento() {
System.out.println("\nEVENTOS disponibles:");
for (int i = 0; i < eventos.size(); i++) {
System.out.println(i + " - " + eventos.get(i).getNombre());
}
System.out.print("\nSeleccione nº de EVENTO: ");
int num = Integer.parseInt(teclado.nextLine());

/*
* Con try catch, podemos capturar la posible
* excepción que podría ocurrir si el usuario
* nos da una posición que no existe en el ArrayList
* y así obraremos en consecuencia.
*/
try {
eventos.get(num).mostrarProgramacion();
} catch(IndexOutOfBoundsException ex) {
System.out.println("Selección equivocada...");
}
}
}

578
Siguiente paso.

Una de las cosas que nos piden es crear dos eventos concretos: Tecnotic y Softhard.
El programa tendrá una opción para que el usuario pueda crear los Eventos que quiera, pero estos dos los vamos a dejar creados directamente en el código (lo que se llama hardcodear)
Esto permite que nada más arrancar el programa, ya tengamos dos eventos con los que poder trabajar.

Así que en la clase principal, añadimos este método:
Código: [Seleccionar]
/*
* Crearemos dos eventos via código para que el
* programa comience con algunos datos con los
* que trabajar
*/
private static void crearEventosPorDefecto() {

/*
* Recordamos que un evento tiene los atributos:
* nombre, fecha, organizador, facultad que organiza,
* temática y salones disponibles para actividades
*/
Evento tecnotic = new Evento("Tecnotic", "03/02/2021", "Ismael Clemente",
"MIT Club of Spain", "IA aplicada en operaciones bursátiles", 5);
Evento softhard = new Evento("Softhard", "14/03/2021", "ParqueSoft",
"Universidad Antonio Jose Camacho", "Software Libre en Seguridad Informática", 3);
//Eventos creados, los agregamos al ArrayList que los almacena
eventos.add(tecnotic);
eventos.add(softhard);
}

Y para que esto se ejecute nada más comenzar el programa, invocamos este método en al primera línea del método main()

Código: [Seleccionar]
public static void main(String[] args) {

crearEventosPorDefecto(); //Invocamos método que nos proporciona dos eventos.

String opcion = "";//Variable para recoger opcion del usuario

do {
System.out.println("\n\t\tMENU EVENTOS");
System.out.println("\t\t---- -------\n");
System.out.println("[1] - Crear nuevo EVENTO");
System.out.println("[2] - Crear nueva ACTIVIDAD");
..............

Como hemos dicho, ahora al arrancar el programa, ya tenemos dos Eventos.
Estos Eventos, no tienen Actividades todavía, ya crearemos más adelante el código necesario para añadir Actividades.

Pero lo que vamos a hacer ahora es activar la opción nº 8 de nuestro menú:
Mostrar programación de un EVENTO

Esta opción lo que ha de hacer es mostrar en pantalla los eventos disponibles para que el usuario pueda elegir de cuál quiere ver sus actividades programadas.

Para facilitar esta tarea, deberíamos "enseñarle" a la clase Evento cómo mostrar sus Actividades.
Y también deberíamos enseñarle a la clase Actividad, cómo queremos que muestre sus datos en pantalla.
Así cada clase se hace cargo de lo suyo.

Empecemos por Actividad. Vamos a querer que muestre en pantalla los datos de sus atributos: nombre, expositor, hora, etc..
Para esta necesidad, es habitual sobreescribir el método toString()

Este es un método que TODAS las clases Java heredan automáticamente, pero para que lo usen adecuadamente, hay que sobreescribirlo (Override).
La función de este método es retornar un String con los datos que consideramos representativos de la clase, en este caso, queremos que sean todos los atributos.
Así que eso es lo que haremos, construir un String con todos los datos de los atributos, un poquito formateados para que salgan en pantalla con un mínimo de elegancia.

A la clase Actividad, le añadimos este método:
Código: [Seleccionar]
@Override
public String toString() {
return "\n\t\t----------------\nNombre de ACTIVIDAD: " + nombre
+ "\nExpositor: " + expositor
+ "\nHora: " +  hora + "\nParticipantes: " + participantes
+ "\n\t\t----------------\n";
}

Con esto, Actividad ya sabe como ha de mostrarse en pantalla.
Ahora hay que enseñarle a Evento como mostrar su programación de actividades.

Para mostrar su programación, vamos a pedirle que recorra los "salones, es decir, el arreglo donde se asignan las Actividades y muestre en pantalla los datos de cada Actividad (que acabamos de enseñarle como ha de hacerlo)

Pero hay que tener en cuenta todas las posibilidades.
Es posible que el arreglo no tenga "salones" asignados, es decir, el arreglo este iniciado con "longitud igual a 0" porque se ha utilizado el constructor por defecto.

También es posible que Sí tenga "salones" asignados, pero no tenga ninguna Actividad programada.
De hecho, este es el caso de nuestro eventos Tecnotic y Softhard, tienen salones, pero no tienen actividades.
Esto lo sabremos si al recorrer todas las posiciones del arreglo buscando Actividades, solo encontramos valores null

Y la última posibilidad es que tenga salones y tenga actividades. Es decir, el arreglo tiene al menos un elemento que NO es null
Así que al recorrer el arreglo, por cada elemento primero preguntaremos si NO es null
Si NO lo es, significa que tiene Actividad programada y la mostraremos en pantalla.

Hay que tener en cuenta cada una de estas tres posibilidades y mostrar en pantalla los mensajes necesarios para explicar al usuario qué está ocurriendo en cada caso.

A la clase Evento, le añadimos este método para que sepa mostrar su programación:

Código: [Seleccionar]
public void mostrarProgramacion() {

//Es posible que no hayan salones asignados.
if (salones.length == 0)
System.out.println("\nEste EVENTO no tiene salones de ACTIVIDADES asignados");
else {
/*
* Sí hay salones asignados, pero puede que aun no hayan actividades.
* Si TODAS las posiciones del array de Actividad tienen valor null,
* es que no hay actividades programadas.
*/
boolean hayActividades = false;//Si encontramos al menos 1 actividad, pasará a true
for (int i = 0; i < salones.length; i++) {
if (salones[i] != null) {
hayActividades = true; //Sí que hay actividades programadas
System.out.println("\nNº de Salón: " + i);
System.out.println(salones[i]);//Mostramos datos de la Actividad
}
}
/*
* Terminado el bucle FOR, si la variable hayActividades
* conserva valor FALSE, es que no hay actividades
* programadas en este Evento y lo indicamos en pantalla.
*/
if (!hayActividades)
System.out.println("\nAún no se han programado ACTIVIDADES para este EVENTO");
}
}

Bien, lo siguiente es crear el código en la clase main para que el usuario pueda dar orden de consultar la programación de un Evento.
Como dijimos, la lógica a seguir será mostrar al usuario los eventos disponibles para que elija cuál quiera consultar, y al evento elegido le pediremos que muestre sus actividades.

En la clase principal, añadimos este método:
Código: [Seleccionar]
/*
* Muestra al usuario los Eventos disponibles para que
* elija uno y saldrá en pantalla sus Actividades programadas,
* si es que las tiene.
*/
private static void mostrarActividadesEvento() {
System.out.println("\nEVENTOS disponibles:");
for (int i = 0; i < eventos.size(); i++) {
System.out.println(i + " - " + eventos.get(i).getNombre());
}
System.out.print("\nSeleccione nº de EVENTO: ");
int num = Integer.parseInt(teclado.nextLine());

/*
* Con try catch, podemos capturar la posible
* excepción que podría ocurrir si el usuario
* nos da una posición que no existe en el ArrayList
* y así obraremos en consecuencia.
*/
try {
eventos.get(num).mostrarProgramacion();
} catch(IndexOutOfBoundsException ex) {
System.out.println("Selección equivocada...");
}
}

Y para que funcione, en el método main(), vamos al case 8 del switch, borramos la línea donde informábamos que estaba en construcción y añadimos una llamada a este nuevo método.

Citar
         switch(opcion) {
         case "0":
            System.out.println("\n\t\t--FIN DE PROGRAMA--");
            break;
         case "1":
            System.out.println("\nEn construccion...");
            break;
         case "2":
            System.out.println("\nEn construccion...");
            break;
         case "3":
            System.out.println("\nEn construccion...");
            break;
         case "4":
            System.out.println("\nEn construccion...");
            break;
         case "5":
            System.out.println("\nEn construccion...");
            break;
         case "6":
            System.out.println("\nEn construccion...");
            break;
         case "7":
            System.out.println("\nEn construccion...");
            break;
         case "8":
            mostrarActividadesEvento();
            break;
         default:
            System.out.println("\nOpción no válida...");
         }

Y así ya tenemos la opción nº 8 funcionando, y podemos ver la programación de nuestros dos eventos. Aunque como ya hemos dicho, no hay nada programado todavía...

En pantalla podemos ver algo como esto:
Citar
      MENU EVENTOS
      ---- -------

[1] - Crear nuevo EVENTO
[2] - Crear nueva ACTIVIDAD
[3] - Mostrar ACTIVIDAD con mayor número de participantes
[4] - Mostrar ACTIVIDAD con menor número de participantes
[5] - Mostrar total participantes de un EVENTO
[6] - Mostrar ACTIVIDADES ordenadas de mayor a menos número de participantes
[7] - Consultar ACTIVIDADES de un expositor
[8] - Mostrar programación de un EVENTO

[ 0] - SALIR del programa

Escoja opción: 8

EVENTOS disponibles:
0 - Tecnotic
1 - Softhard

Seleccione nº de EVENTO: 0

Aún no se han programado ACTIVIDADES para este EVENTO

Pulse ENTER para seguir...

579
hasta el momenton voy entediento el codigo con los comentarios que ahi entre lineas lo que no eh entendido por la que se importa el arrayslist o cual es la funcion de el??

Buena pregunta.

Un ArrayList, es muy parecido a un arreglo "normal".
Su utilidad es la misma: contener muchas variables u objetos, en un único objeto, y poder acceder a ellos usando un indice para señalar a cada uno de sus elementos.

Pero el ArrayList es más avanzado y tiene una diferencia fundamental: no tiene un tamaño fijo.

Un arreglo normal, cuando se inicia, hay que darle un tamaño y este no puede cambiar.
Si lo inicio dándole una longitud de 5 elementos, solo podrá contener eso: 5 elementos.
Es una colección estática, no podemos variar su tamaño.

En cambio un ArrayList se puede iniciar sin darle ningún tamaño fijo. Así que permite que podamos añadirle todos los elementos que queramos sin restricciones, su tamaño irá creciendo cuando añadamos elementos o disminuyendo cuando pidamos eliminarlos.
Es una colección dinámica, su tamaño se va ajustando según le entran o salen elementos.

Entonces, cuando queramos modelar una entidad que va a tener una cantidad de elementos fija, pues vamos a preferir usar un arreglo normal.
Es lo que hemos hecho con la clase Evento, porque hemos decidido que cada Evento va a tener un número de "salones" concreto, este número se decide mediante su constructor.

En cambio, en el programa principal, vamos a querer que el usuario pueda crear todos los Eventos que el quiera.
En el "mundo real", esta aplicación sería para gestionar los Eventos que se producen en una ciudad, o en una región, a lo largo de todo el año.
¿Cuántos Eventos podrían ser?... Pues no lo sabemos.., pueden ser decenas, o centenares...

Entonces, no nos interesa usar un arreglo "normal", porque voy a tener que darle un tamaño fijo. Si le doy tamaño de 200 por ejemplo, pues ese sería el límite de eventos.
Si resulta que a lo largo del año ocurren más de 200 eventos.., pues nuestra aplicación no sería capaz de gestionarlos todos si optamos por usar un arreglo normal.

En cambio, usando una colección dinámica como ArrayList (no es la única que existe en Java), no tendríamos ningún problema. Ningún evento quedaría fuera de nuestra aplicación, porque no hay límite para albergarlos.

Esa es la ventaja del ArrayList, no tiene tamaño fijo y nos interesará usarlo cuando nuestro programa tenga que gestionar una cantidad indeterminada de datos

580
Vamos a ir desarrollándolo paso a paso.

Tenemos las clases principales, pero esto por si solo no funciona, no es un programa ejecutable.

Necesitamos otra clase, la clase "main" principal que hace que el programa se ejecute y será quien se encargue de mostrar un menú al usuario para que elija las tareas que quiere realizar.

Podemos comenzar creando el "esqueleto" de este menú. Vamos a mostrar en pantalla las opciones disponibles y dejar que el usuario elija la que quiera, pero las opciones aún no tendrán funcionalidad, estas las iremos añadiendo poco a poco.
De momento solo mostraremos el mensaje "En construcción..."

Pero ya sí tenemos un programa que podemos ejecutar, no hace gran cosa, pero se puede poner en marcha.

Sí vamos a poner ya como atributo global, un ArrayList donde se irán almacenando los Eventos que el usuario quiera crear.
Y un objeto Scanner para poder leer por teclado lo que el usuario quiera introducir.

Y también un método muy simple llamado pausa() que su función será detener la ejecución del programa hasta que se pulse la tecla ENTER.
De este modo, podemos "pausar" el programa para que el usuario lea los mensaje en pantalla y avanzar cuando él así lo decida.


De nuevo insisto en la importancia de que entiendas cada línea de código antes de seguir con los pasos siguientes.
Que no te queden dudas sobre cómo se comporta el bucle do..while() que estamos usando, o que hace el switch..., o por qué estamos usando un ArrayList para guardar Eventos y no estamos usando un arreglo primitivo "normal y corriente".

Pregunta lo que sea.

Código: [Seleccionar]
import java.util.ArrayList;
import java.util.Scanner;

public class MenuEventos {

//Aquí se almacenarán los Eventos
private static ArrayList<Evento> eventos = new ArrayList<Evento>();
//Objeto Scanner para leer datos por teclado
private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {

String opcion = "";//Variable para recoger opcion del usuario

do {
System.out.println("\n\t\tMENU EVENTOS");
System.out.println("\t\t---- -------\n");
System.out.println("[1] - Crear nuevo EVENTO");
System.out.println("[2] - Crear nueva ACTIVIDAD");
System.out.println("[3] - Mostrar ACTIVIDAD con mayor número de participantes");
System.out.println("[4] - Mostrar ACTIVIDAD con menor número de participantes");
System.out.println("[5] - Mostrar total participantes de un EVENTO");
System.out.println("[6] - Mostrar ACTIVIDADES ordenadas de mayor a menos número de participantes");
System.out.println("[7] - Consultar ACTIVIDADES de un expositor");
System.out.println("[8] - Mostrar programación de un EVENTO");
System.out.println("\n[0] - SALIR del programa");
System.out.print("\nEscoja opción: ");
opcion = teclado.nextLine();
//Evaluamos opcion escogida
switch(opcion) {
case "0":
System.out.println("\n\t\t--FIN DE PROGRAMA--");
break;
case "1":
System.out.println("\nEn construccion...");
break;
case "2":
System.out.println("\nEn construccion...");
break;
case "3":
System.out.println("\nEn construccion...");
break;
case "4":
System.out.println("\nEn construccion...");
break;
case "5":
System.out.println("\nEn construccion...");
break;
case "6":
System.out.println("\nEn construccion...");
break;
case "7":
System.out.println("\nEn construccion...");
break;
case "8":
System.out.println("\nEn construccion...");
break;
default:
System.out.println("\nOpción no válida...");
}
pausa();
} while(!opcion.equals("0"));
}

/*
* Sencillo método que pausa la ejecución del programa
* hasta que el usuario pulse ENTER/INTRO
*/
private static void pausa() {
System.out.println("\nPulse ENTER para seguir...\n");
teclado.nextLine();
}

}

Páginas: 1 ... 24 25 26 27 28 [29] 30 31 32 33 34 ... 50

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".