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 ... 9 10 11 12 13 [14] 15 16 17 18 19 ... 50
261
¿Y en que parte tienes problemas?
¿Qué es lo que no entiendes?

¿Qué clases has identificado tú? Es evidente que habrá que escribir las clases Socio y Libro.
Pero, ¿hay más clases?

¿Y en que lenguaje tienes que escribirlo? ¿En modo texto/consola o con interfaz gráfica?

262
Ahora sí parece estar todo correcto  :D

263
Estas lineas...
Código: [Seleccionar]
ListaFamosos ListaCantantes = new ListaFamosos();
//System.out.println ("Aquí lista con unos tres cantantes: " + ListaCantantesFamosos.getlistaFamosos() + ".");

La clase ListaFamosos no existe, tu clase se llama: ListaCantantesFamosos
ListaFamosos es el nombre que le has dado al atributo de tipo ArrayList, no es una clase, es un atributo de clase.
Y por tanto sería más correcto que su nombre comenzase en minúscula:listaFamosos

La siguiente lineas, que has marcado como comentario, también tiene errores.
Estás llamando un método llamado getListaFamosos(), que no has escrito.
Y de haberlo escrito, también fallaría porque lo estás invocando nombrando a su clase ListaCantantesFamosos, cuando lo normal sería invocarlo nombrando al objeto que se llama ListaCantantes (y que también sería más correcto que su nombre comenzase en minúscula)

De los métodos que has escrito, el que mostraría la lista de cantantes es el método numeroCantantes()
Código: [Seleccionar]
    public void numeroCantantes(){
        for (int i = 0; i<ListaFamosos.size(); i++){
            if (i<ListaFamosos.size()){
                System.out.println ("Cantante" + (i+1) + " " + ListaFamosos.get(i));
            }else{System.out.println("No existe nombre para la posición solicitada");}
        }
    }
Dicho método, en principio funcionaría bien, pero tiene una redundancia.
Dentro del bucle for, compruebas si el valor de i es menor que el size() del ArrayList para decidir si tienes una posición válida con la que pedir un valor al get().

En otro contexto, podría estar bien hacer esta comprobación. Pero en este caso, es innecesaria y redundante.
Porque el bucle for, ya tiene una condición que te asegura que la i SOLO tendrá valores menores que el size()
Citar
for (int i = 0; i<ListaFamosos.size(); i++){
Gracias a esa condicion, dentro del bucle for la i jamás tendrá un valor que supere el size(), así que no es necesario comprobarlo con un if.
Puedes confiar en pedirle valores al get() sin temor ninguno
Código: [Seleccionar]
    public void numeroCantantes(){
        for (int i = 0; i<ListaFamosos.size(); i++){
            System.out.println ("Cantante " + (i+1) + " " + ListaFamosos.get(i));
        }
    }

264
Comunidad / Re: proyecto diagramas de clases- ayuda por favor
« en: 14 de Febrero 2022, 17:46 »
Aquí: https://aprenderaprogramar.com/foros/index.php?topic=8230.0

A lo que hice, puedes añadirle los atributos que salen en el diagrama y yo no puse.

265
Esa E es lo que se llama un "tipo genérico", una especie de comodín para cuando no se sabe que tipo se va a utilizar.

Es decir, cuando declaramos un método en una clase, hay que indicar que tipo de dato va a retornar: un Integer, un String, un Persona, un Alumno....

Pero, si lo que estamos creando es una clase pensada para trabajar con CUALQUIER tipo de clase existente y por existir...., ¿cómo vamos a indicar lo que sus métodos retornan si hay, literalmente, infinitas posibilidades?

Eso es lo que pasa con las clases de las Collections de Java. Las List, las Map, las Set...., son interfaces/clases pensadas para coleccionar objetos de cualquier otra clase.
Así que al escribir estas clases, para indicar los tipos de retorno se usa un "tipo genérico", que en si mismo no es nada.

El código del método pop() de la clase Stack, es este:

Citar
public synchronized E pop()
{
    if (elementCount == 0)
        throw new EmptyStackException();

    modCount++;
    E obj = elementData[--elementCount];
 
    // Set topmost element to null to assist the gc in cleanup.
    elementData[elementCount] = null;
    return obj;
}

Con lo que remarco en azul, vemos que se retorna un objeto de tipo E.
¿Qué es tipo E? Pues un genérico.
En realidad no es nada, es una forma de decir que se va a retornar "algo", pero no sabemos que será, porque depende del tipo que escoja el programador cuando declare su propio Stack.

Así, cuando yo quiera usar un Stack y lo declare así:

Código: [Seleccionar]
Stack<String> miPila = new Stack<String>();
El método pop() retornará objetos String.

Y si lo declaro así:
Código: [Seleccionar]
Stack<Integer> miPila = new Stack<Integer>();Pues ahora pop() retornará Integer.

Para eso se usan los genéricos, para hacer que una clase pueda adaptarse a trabajar con objetos de cualquier otra clase.

Por eso el tipo E no es un tipo real, no existe la clase E. Es solo para decirle a Java que ahí puede ir cualquier tipo de clase, no una en concreto.
En ese caso se usa la E, porque es la primera letra de "Element" y suele usarse en las Collections de Java.
Pero se pueden usar otras letras, de hecho, la que más verás frecuentemente es la T de "Type".

Pero da lo mismo usar una que otra, en todos los casos la utilidad es indicar que el código ha de prepararse para usar cualquier tipo de clase.

Hay unas convenciones para elegir letras que describan lo mejor posible la naturaleza de los elementos que, previsiblemente (ya que en realidad puede ser cualquier cosa), se usará en la clase que estemos desarrollando con "tipos genéricos"

Citar
E – Element (usado bastante por Java Collections Framework)
K – Key (Llave, usado en Map)
N – Number (para números)
T – Type (Representa un tipo, es decir, una clase)
V – Value (representa el valor, también se usa en mapas)
S,U, etc. – usado para representar otros tipos.

266
Desconozco ese algoritmo.

En youtube alguien lo explica, a ver si puede servirte: https://www.youtube.com/watch?v=zhTdhoyMfO4

267
Se me ocurre que puedes recorrer carácter a carácter con un un bucle.
Entonces, las posiciones pares las muestras como mayúsuculas y las impares como minúsculas:

Código: [Seleccionar]
static void Main(string[] args)
        {
            String cadena = "hola caracola";

            for (int i = 0; i < cadena.Length; i++)
                if (i % 2 == 0)
                    Console.Write(cadena[i].ToString().ToUpper());
                else
                    Console.Write(cadena[i].ToString().ToLower());
        }

268
Vamos a diseccionar la clase principal, que podemos llamar Universidad
Como variables de ámbito global, tendremos un array para los 5 Estudiantes que se han de registrar y un objeto Scanner para pedir datos por teclado.
En mi caso, además he optado por predefinir en un array los nombres de las 5 asignaturas.
De esta forma, ya no es un dato que haya que pedir por teclado cada vez que registramos una asignatura.
Y además, nos aseguramos de que cada Estudiante va a tener las mismas 5 Asignaturas, y en el mismo orden, porque este dato ya no depende de lo que introduzca el usuario.

Código: [Seleccionar]
public class Universidad {

//Nombre de las Asignaturas están predefinidas.
private static final String[] ASIGNATURAS = new String[] {"Matematicas",
"Historia", "Ciencias", "Literatura", "Informatica"};
//Array de Estudiantes
private static Estudiante[] estudiantes;

private static Scanner teclado = new Scanner(System.in);

El método main(), lo que hará será mostrar un menú de opciones y evaluar con un switch la selección del usuario.
Según lo que elija, se invocarán distintos métodos.

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

int opcion = 0;

do {
System.out.println("\n\t\tMENU UNIVERSIDAD");
System.out.println("\t\t---- -----------\n");
System.out.println("[1] -- Registrar nuevos Estudiantes");
System.out.println("[2] -- Listar notas definitivas de Asignaturas por cada Estudiante");
System.out.println("[3] -- Listar promedio general de cada Estudiante");
System.out.println("[4] -- Listar promedio de nota definitiva de todos los Estudiantes por Asignatura");
System.out.println("[9] -- TERMINAR PROGRAMA");
System.out.print("Opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
registrarNuevosEstudiantes();
break;
case 2:
listarNotasDefinitivas();
break;
case 3:
listarPromedioEstudiantes();
break;
case 4:
listarPromediosNotasDefinitivas();
break;
case 9:
System.out.println("\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opción equivocada");
}
} while(opcion != 9);

}

Veamos el primer método: registrarNuevosEstudiantes()
Lo que hará será inicializar el array de Estudiantes y con un bucle pedir datos para crear 5 Estudiantes.
Por cada Estudiante, usará otro bucle para crear 5 Asignaturas..
Y por cada Asignatura, usará un tercer bucle para pedir las 3 notas parciales.

Así que aunque es un método sencillo, requiere de tres bucles anidados y por eso tiene tantas líneas de código.
Código: [Seleccionar]
private static void registrarNuevosEstudiantes() {

//Inicializamos array de Estudiantes
estudiantes = new Estudiante[5];

//Por cada Estudiante, registraremos 5 Asignaturas, con 3 notas parciales
for (int est = 0; est < estudiantes.length; est++) {
System.out.println("\n\nRegistrando Estudiante #" + (est+1));
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
//Registramos Estudiante en el array
estudiantes[est] = new Estudiante(nombre);

//Para este Estudiante, registramos ahora 5 Asignaturas
for (int asig = 0; asig < ASIGNATURAS.length; asig++) {
//Construimos la Asignatura, tomando el nombre del array predefinido
Asignatura asignatura = new Asignatura(ASIGNATURAS[asig]);

//Ahora, hay que pedir 3 notas parciales para esta Asignatura
System.out.println("\nNotas parciales de " + ASIGNATURAS[asig]);
for (int i = 0; i < 3; i++) {
System.out.print("Parcial #" + (i+1) + ": ");
int parcial = Integer.parseInt(teclado.nextLine());
//Registramos parcial en la Asignatura, indicando la posición donde debe registrarse
asignatura.registrarNotaParcial(parcial, i);
}

/*
* Ya tenemos Asignatura con las 3 notas parciales.
* La registramos en el Estudiante, indicando la posicion donde registrarse
*/
estudiantes[est].registrarAsignatura(asignatura, asig);
}
//Aqui termina el bucle para registrar 5 Asignaturas.
//Ahora se volverá a repetir el ciclo para otro Estudiante, hasta completar los 5
}
}

Ahora el método listarNotasDefinitivas().
Lo que hace es mostrar, por cada Asignatura, la nota definitiva que ha obtenido cada Estudiante.
Así que con un bucle se recorren las asignaturas y con otro anidado se recorren los estudiantes para pedirles la nota definitiva, indicándoles que posición de su array han de consultar.
He aquí la ventaja de predefinir las asignaturas para que se llamen igual y se registren en el mismo orden.
Todos los estudiantes tienen Matematicas en la posición
  • , Historia en la [1], ....

No hace falta buscar asignaturas por nombre, se indica la posición del array de asignaturas predefinidas en la clase main, porque coincide con las posicione del array que cada Estudiante posee

Código: [Seleccionar]
private static void listarNotasDefinitivas() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tNOTAS DEFINITIVAS POR ESTUDIANTES");
//Recorremos cada Asignatura
for (int asig= 0; asig < ASIGNATURAS.length; asig++) {
System.out.println("\n- Asignatura: " + ASIGNATURAS[asig]);
//Recorremos cada Estudiante para obtener su nota en la Asignatura actual
for (Estudiante estu: estudiantes) {
System.out.println("Nombre: " + estu.getNombre());
System.out.println("Nota Definitiva: " + estu.getNotaDeAsignatura(asig));
}
}
}
}


Luego viene el método: listarPromedioEstudiantes()
Muy sencillo, solo hay que recorrer Estudiantes y pedirles su promedio general.
Este promedio se calcula a partir de sus 5 notas definitivas de cada Asignatura, y la clase Estudiante ya sabe calcularlo ella sola.
Código: [Seleccionar]
private static void listarPromedioEstudiantes() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tPROMEDIO GENERAL POR ESTUDIANTES");
//Recorremos Estudiantes y les pedimos su promedio
for (Estudiante estu: estudiantes) {
System.out.println("\nNombre: " + estu.getNombre());
System.out.println("Promedio General: " + estu.getPromedioGeneral());
}
}
}

Por último, el método listarPromediosNotasDefinitivas().
Aquí hay que recorrer cada Asignatura. Y por cada una de ellas, recorrer los 5 Estudiantes y sumar sus notas definitivas para dicha asignatura.
A partir de esta suma, calculamos el promedio entre los estudiantes de esta asignatura.
Código: [Seleccionar]
private static void listarPromediosNotasDefinitivas() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tPROMEDIOS NOTAS DEFINITIVAS");
//Recorremos Asignaturas
for (int asig= 0; asig < ASIGNATURAS.length; asig++) {
System.out.println("\nAsignatura: " + ASIGNATURAS[asig]);
/*
* Por cada Asignatura, sumamos las notas definitivas de los
* 5 Estudiantes. Con esta suma, luego calcularemos el promedio
*/
int sumaNotas = 0;
for (Estudiante estu: estudiantes)
sumaNotas += estu.getNotaDeAsignatura(asig);
//Tenemos la suma, calculamos promedio
System.out.println("Promedio de notas: " + (sumaNotas/estudiantes.length));
}
}
}

Y eso es todo. Puede ser un poco lioso en cuanto a saber si se está pidiendo el promedio de una asignatura de un estudiante, o el promedio de una asignatura para los 5 estudiantes, o el promedio de todas las asignaturas para un solo estudiante...  :o

No recuerdo como lo resolvimos la otra vez, probablemente fuera distinto. Espero que esta vez hayamos dado una solución más clara y comprensible.

Un saludo.

Por cierto, dejo aquí el código completo de la clase principal:

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

public class Universidad {

//Nombre de las Asignaturas están predefinidas.
private static final String[] ASIGNATURAS = new String[] {"Matematicas",
"Historia", "Ciencias", "Literatura", "Informatica"};
//Array de Estudiantes
private static Estudiante[] estudiantes;

private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {

int opcion = 0;

do {
System.out.println("\n\t\tMENU UNIVERSIDAD");
System.out.println("\t\t---- -----------\n");
System.out.println("[1] -- Registrar nuevos Estudiantes");
System.out.println("[2] -- Listar notas definitivas de Asignaturas por cada Estudiante");
System.out.println("[3] -- Listar promedio general de cada Estudiante");
System.out.println("[4] -- Listar promedio de nota definitiva de todos los Estudiantes por Asignatura");
System.out.println("[9] -- TERMINAR PROGRAMA");
System.out.print("Opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
registrarNuevosEstudiantes();
break;
case 2:
listarNotasDefinitivas();
break;
case 3:
listarPromedioEstudiantes();
break;
case 4:
listarPromediosNotasDefinitivas();
break;
case 9:
System.out.println("\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opción equivocada");
}
} while(opcion != 9);

}

private static void registrarNuevosEstudiantes() {

//Inicializamos array de Estudiantes
estudiantes = new Estudiante[5];

//Por cada Estudiante, registraremos 5 Asignaturas, con 3 notas parciales
for (int est = 0; est < estudiantes.length; est++) {
System.out.println("\n\nRegistrando Estudiante #" + (est+1));
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
//Registramos Estudiante en el array
estudiantes[est] = new Estudiante(nombre);

//Para este Estudiante, registramos ahora 5 Asignaturas
for (int asig = 0; asig < ASIGNATURAS.length; asig++) {
//Construimos la Asignatura, tomando el nombre del array predefinido
Asignatura asignatura = new Asignatura(ASIGNATURAS[asig]);

//Ahora, hay que pedir 3 notas parciales para esta Asignatura
System.out.println("\nNotas parciales de " + ASIGNATURAS[asig]);
for (int i = 0; i < 3; i++) {
System.out.print("Parcial #" + (i+1) + ": ");
int parcial = Integer.parseInt(teclado.nextLine());
//Registramos parcial en la Asignatura, indicando la posicion donde debe registrarse
asignatura.registrarNotaParcial(parcial, i);
}

/*
* Ya tenemos Asignatura con las 3 notas parciales.
* La registramos en el Estudiante, indicando la posición donde registrarse
*/
estudiantes[est].registrarAsignatura(asignatura, asig);
}
//Aqui termina el bucle para registrar 5 Asignaturas.
//Ahora se volverá a repetir el ciclo para otro Estudiante, hasta completar los 5
}
}

private static void listarNotasDefinitivas() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tNOTAS DEFINITIVAS POR ESTUDIANTES");
//Recorremos cada Asignatura
for (int asig= 0; asig < ASIGNATURAS.length; asig++) {
System.out.println("\n- Asignatura: " + ASIGNATURAS[asig]);
//Recorremos cada Estudiante para obtener su nota en la Asignatura actual
for (Estudiante estu: estudiantes) {
System.out.println("Nombre: " + estu.getNombre());
System.out.println("Nota Definitiva: " + estu.getNotaDeAsignatura(asig));
}
}
}
}

private static void listarPromedioEstudiantes() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tPROMEDIO GENERAL POR ESTUDIANTES");
//Recorremos Estudiantes y les pedimos su promedio
for (Estudiante estu: estudiantes) {
System.out.println("\nNombre: " + estu.getNombre());
System.out.println("Promedio General: " + estu.getPromedioGeneral());
}
}
}

private static void listarPromediosNotasDefinitivas() {
if (estudiantes == null)
System.out.println("No hay Estudiantes registrados.");
else {
System.out.println("\n\tPROMEDIOS NOTAS DEFINITIVAS");
//Recorremos Asignaturas
for (int asig= 0; asig < ASIGNATURAS.length; asig++) {
System.out.println("\nAsignatura: " + ASIGNATURAS[asig]);
/*
* Por cada Asignatura, sumamos las notas definitivas de los
* 5 Estudiantes. Con esta suma, luego calcularemos el promedio
*/
int sumaNotas = 0;
for (Estudiante estu: estudiantes)
sumaNotas += estu.getNotaDeAsignatura(asig);
//Tenemos la suma, calculamos promedio
System.out.println("Promedio de notas: " + (sumaNotas/estudiantes.length));
}
}
}
}

269
Se propone el siguiente ejercicio de programación en Java:

Citar
Caso Universidad: Haciendo uso de la programación orientada a objetos complete el ejercicio propuesto sobre el registro de notas de los estudiantes de la universidad que brinde las funcionalidades de:

  • registrar la nota de 5 estudiantes en 5 asignaturas diferentes
  • Obtenga una nota definitiva de cada asignatura para cada estudiante se tienen 3 notas parciales en cada asignatura (todas con igualdad de valor)
  • Un promedio general de cada estudiante en todas sus asignaturas.
  • Un promedio de la nota definitiva de todos los estudiantes por cada asignatura

Este ejercicio ya fue resuelto en un mensaje anterior hace tiempo, pero por si quizás no quedó claro, lo resolvemos de nuevo.

Se pide resolver mediante POO, así que lo primero es identificar la entidades que intervienen y podrían requerir ser modeladas mediante clases.
Normalmente, modelaremos como clases aquellas entidades que se componen de "otras cosas" y/o tienen algunas funcionalidades concretas que conviene que las resuelvan ellas mismas.

Nos dicen que hay Estudiantes, que tienen Asignaturas. Y que cada Asignatura tendría 3 notas parciales, a partir de las cuales se podría calcular la nota definitiva para dicha Asignatura.

Estudiante y Asignatura es evidente que serán clases, ya que están compuestas de "otras cosas".
Un Estudiante se compone de Asignaturas y de al menos un nombre, aunque no se indique en el enunciado.
Además sería útil que un Estudiante, por si solo, tenga funcionalidades como darnos el promedio de las notas de sus Asignaturas

Una Asignatura se compone de tres notas parciales y también habría que darle un nombre.
Y también interesa que por si sola sepa hacer cosas como calcular su nota definitiva mediante las tres notas parciales que la componen

Una nota parcial no se compone de nada, es simplemente un valor int, o double si lo preferimos. Ni requiere poseer ninguna funcionalidad especial, así que no será una clase.

Una nota definitiva sí se compone de tres notas parciales. ¿Debería ser una clase?
Podría serlo... Quizás si el ejercicio fuera más avanzado y las notas definitivas tuvieran un tratamiento más especial, entonces interesaría modelarlo como una clase.

Pero en este caso no sería necesario, aquí la nota definitiva en realidad es un mero cálculo aritmético que lo único que ha de hacer es mostrarse en pantalla cuando se requiera. Y para resolver eso basta con usar un método, no hace falta modelar una clase.

Así que tendríamos la clase Asignatura.
Se compone de un nombre y tres notas parciales, que las podemos agrupar en un array
Mediante constructor le damos un nombre.
Luego con métodos, podemos registrar una nota en una posición concreta del array.
Y también calcular y retornar la nota definitiva. (por eso no requiere modelarse como una clase)
Código: [Seleccionar]
public class Asignatura {
//Cada asignatura tiene tres notas parciales
private int[] parciales = new int[3];
private String nombre;

public Asignatura(String nombre) {
this.nombre = nombre;
}

public String getNombre() {
return nombre;
}

/*
* Registra una nota parcial en la posición del array que
* se indique.
*/
public void registrarNotaParcial(int nota, int posicion) {
parciales[posicion] = nota;
}

/*
* Todas las notas tienen el mismo peso para calcular la nota
* definitiva. Así que basta con calcular el valor medio de las tres.
*/
public int getNotaDefinitiva() {
int sumaNotas = parciales[0] + parciales[1] + parciales[2];
return sumaNotas / 3;
}
}

Luego tendríamos la clase Estudiante.
Se compone de nombre, que recibe por constructor, y 5 objetos Asignatura, que también agruparemos en un array.

Con métodos podemos registrar una Asignatura en una posición concreta del array.
También podemos obtener la nota definitiva de una Asignatura concreta, indicando la posición del array que se quiere consultar.

Y también podemos obtener el "promedio general" de este Estudiante, es decir, sumar las notas definitivas de todas sus Asignaturas y calcular el promedio de dicha suma.
Código: [Seleccionar]
public class Estudiante {

//Cada Estudiante tiene 5 asignaturas
private Asignatura[] asignaturas = new Asignatura[5];
private String nombre;

public Estudiante(String nombre) {
this.nombre = nombre;
}

public String getNombre() {
return nombre;
}

/*
* Registra una Asignatura en la posicion del array que
* se le indique
*/
public void registrarAsignatura(Asignatura asign, int posicion) {
asignaturas[posicion] = asign;
}

/*
* Retorna la nota definitiva de la asignatura que se encuentra
* en la posicion del array indicada.
*/
public int getNotaDeAsignatura(int posicion) {
return asignaturas[posicion].getNotaDefinitiva();
}

/*
* Hace un promedio general de todas las asignaturas
* de este estudiante
*/
public int getPromedioGeneral() {
//Sumamos las notas definitivas de sus asignaturas
int sumaNotas = 0;
for (Asignatura asig: asignaturas)
sumaNotas += asig.getNotaDefinitiva();
//Retornamos el promedio
return sumaNotas / 5;
}

}

Y con esto ya podemos componer la clase principal donde se pondrán en marcha todas las funcionalidades de la aplicación.
Lo vemos en el siguiente mensaje.

270
Aprender a programar desde cero / Re: Ayuda con mi proyecto!
« en: 09 de Febrero 2022, 23:59 »
Hola.
Lamento decir que no, no pude continuarlo en su momento al tratarse de un proyecto de tanta magnitud.
De hecho, ahora he leído un poco este hilo y yo mismo me abrumo :o por la cantidad de código que publiqué, hace ya casi 1 año.

 :( Ojalá me sobrara tiempo para dedicar a ejercicios como este

271
Un ActionListener es algo que ocurre durante un evento concreto (cuando se pulsa un determinado botón).
Es un proceso individual, muy corto y que suele estar al margen del flujo general del programa.

Así que yo ni le pondría throws ni nada.
Las excepciones que se tengan que controlar, las trataría todas dentro del ActionListener, no hay necesidad de "lanzarlas" hacia fuera.

Las excepciones que puedan ocurrir durante la creación de un soldado, son problemas que tendrán que resolverse durante ese mismo proceso.
Al resto de procesos del programa les va a dar igual, no es asunto de ellos.

Si la acción crear soldado les dice (hace un throw) a los demás procesos:
-Eh tíos, no he podido crear un soldado, porque el usuario se divierte escribiendo palabrotas en lugar de darme números enteros para la vida y la armadura

Los demás procesos se encogerán de hombros porque no les afecta a ellos para poder hacer sus cosas.
Por ejemplo el proceso que actualiza el JList le diría:
- ¿Y a mí que me cuentas? Mira, si logras crear un soldado, actualizaré el JList de la interfaz para mostrarlo.
Y si no lo consigues, pues casi mejor porque así no tendré que hacer nada y seguiré rascándome el ombligo.
Así que tus problemas son cosa tuya...


Bueno, con esta dramatización  ;D lo que vengo a decir es que la acción de crear un soldado, es una subtarea independiente, así que las excepciones no es necesario lanzarlas a ningún sitio. Se tratan de manera interna con try catch y ya está.

Sería distinto si por ejemplo hubiera otro proceso que se ha quedado detenido expresamente a la espera de la creación de un soldado.
Aquí si podríamos hacer un throw porque este proceso, para poder continuar, necesitaría o bien recibir un soldado, o si no una excepción para saber que no ha sido posible y ya entonces su flujo irá por un lado o por otro.

Resumiendo, al tratar excepciones no siempre es necesario lanzarlas con throw.
Las lanzaremos o no, según si podemos (o queremos, va un poco a gusto de cada uno), resolverlas de forma interna al proceso donde se han generado o bien resolverlas de forma externa, mediante un proceso ajeno al que ha "sufrido" la excepción.

272
El parseo está bien en dentro del try.
Lo que no estába bien, es el try dentro de la condición de ese if.

Este era tu código:
Código: [Seleccionar]
            if (jtVida.getText().isEmpty() || jtArmadura.getText().isEmpty()) {
                JOptionPane.showMessageDialog(null, "El campo no puede estar vacío");
                try {
                    Integer valor = Integer.parseInt(jtVida.getText());
                    Integer valor2 = Integer.parseInt(jtArmadura.getText());
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(null, "El valor tiene que ser numérico");
                }
            }

Ahí estas diciendo:
-Si el campo vida o el campo armadura están vacíos, alerto de que no deben estarlo y a continuación intento el parseo.
Y ese es el error, intentar el parseo cuando YA SABES que uno (o ambos) de los campos está vacío.

Por eso te da un error indicando que no se puede parsear una cadena vacía (que proviene de un campo vacío)
Citar
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: ""
   at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
   at java.lang.Integer.parseInt(Integer.java:592)
   at java.lang.Integer.parseInt(Integer.java:615)


En el código que yo propuse, a ese if le añado un else, que será donde intentaremos el parseo.
Citar
            if (jtVida.getText().isEmpty() || jtArmadura.getText().isEmpty())
                JOptionPane.showMessageDialog(null, "El campo no puede estar vacío");
            else { //Ningún campo está vacío, intentamos el parseo
                try {
                    Integer valor = Integer.parseInt(jtVida.getText());
                    Integer valor2 = Integer.parseInt(jtArmadura.getText());
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(null, "El valor tiene que ser numérico");
                }
            }

Ahí, estoy diciendo:

-Si el campo vida o el campo armadura están vacíos, alerto de que no deben estarlo(y no hacemos nada más, el usuario tendrá que corregir los campos y volver a pulsar el botón)
Si no, es decir, cuando ambos campos contienen algún texto, entonces intentamos el parseo



Espero haberme explicado mejor ahora.

273
Hola.
Muy buena la figura  :D

Pero creo que no habría forma de reducir el código, ni conseguir darle más elegancia.
Al menos a mí no se me ocurre ninguna.

El propósito de fillRect() no es hacer dibujos "complejos", así que inevitablemente, necesitas decenas y decenas de líneas para hacer una figura tan elaborada.

Un saludo.

274
Bueno, yo ahí lo que veo "raro" es que, tras confirmarse que los campos están vacíos, igualmente intentas parsearlos a Integer. Esto último habría que hacerlo, en el caso de confirmar que NO están vacíos.
Citar
            if (jtVida.getText().isEmpty() || jtArmadura.getText().isEmpty())
                JOptionPane.showMessageDialog(null, "El campo no puede estar vacío");
            else { //Ningún campo está vacío, intentamos el parseo
                try {
                    Integer valor = Integer.parseInt(jtVida.getText());
                    Integer valor2 = Integer.parseInt(jtArmadura.getText());
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(null, "El valor tiene que ser numérico");
                }
            }

275
Hola.
A ver, para meterme en contexto, he comenzado a hacer el programa a mi manera, aunque no he podido terminarlo por completo todavía, porque ando escaso de tiempo.

Las clases principales apenas hay diferencias respecto a las tuyas.

Tenemos una clase Contrato, preferiblemente abstracta, de la que derivan dos clases: Consultor y Tecnico

Contrato
Código: [Seleccionar]
ublic abstract class Contrato implements Serializable {

protected String id;
protected String nombre;
protected LocalDate fechaInicio;
protected LocalDate fechaFin;
protected double salario;

public Contrato(String id, String nombre, double salario) {
this.id = id;
this.nombre = nombre;
this.salario = salario;
fechaInicio = LocalDate.now();
fechaFin = null;
}

public String getId() {
return id;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public LocalDate getFechaInicio() {
return fechaInicio;
}

public LocalDate getFechaFin() {
return fechaFin;
}

public void darDeBaja() {
fechaFin = LocalDate.now();
}

public double getSalario() {
return salario;
}

public void setSalario(double salario) {
this.salario = salario;
}

@Override
public String toString() {
return String.format("ID: %s, Nombre: %s, Salario: %.2f\nInicio: %s, Fin :%s",
id, nombre, salario, fechaInicio.toString(), fechaFin==null?"":fechaFin.toString());
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Contrato) {
Contrato otroContrato = (Contrato) obj;
return id.equals(otroContrato.id);
}
else
return false;
}

}

Consultor
Código: [Seleccionar]
public final class Consultor extends Contrato {

private String labor;

public Consultor(String id, String nombre, double salario, String labor) {
super(id, nombre, salario);
this.labor = labor;
}

public String getLabor() {
return labor;
}

public void setLabor(String labor) {
this.labor = labor;
}

@Override
public String toString() {
return String.format("%s\nLabor: %s", super.toString(), labor);
}

}

Tecnico
Código: [Seleccionar]
public class Tecnico extends Contrato {

private int proyectosLiderados;

public Tecnico(String id, String nombre, double salario) {
super(id, nombre, salario);
proyectosLiderados = 0;
}

public int getProyectosLiderados() {
return proyectosLiderados;
}

public void contarProyectoLiderado() {
proyectosLiderados++;
}

@Override
public double getSalario() {
double salario = super.getSalario();
double bonus = salario * 5 / 100;
//Incremento del 5% por cada proyecto liderado
return salario + bonus * proyectosLiderados;
}

@Override
public String toString() {
return String.format("%s\nProyectos Liderados: %d",
super.toString(), proyectosLiderados);
}

}

De esta última clase, derivan otras dos subclases:
Programador
Código: [Seleccionar]
public final class Programador extends Tecnico {

private String lenguaje;

public Programador(String id, String nombre, double salario, String lenguaje) {
super(id, nombre, salario);
this.lenguaje = lenguaje;
}

@Override
public double getSalario() {
//Incrementa 20% si es experto en Java
if (lenguaje.equals("Java"))
return super.getSalario() + (super.getSalario() * 20 / 100);
else
return super.getSalario();
}

@Override
public String toString() {
return String.format("%s\nLenguaje: %s", super.toString(), lenguaje);
}

}

Lider
Código: [Seleccionar]
public class Lider extends Tecnico {

private ArrayList<Tecnico> equipo;

public Lider(String id, String nombre, double salario) {
super(id, nombre, salario);
equipo = new ArrayList<Tecnico>();
}

public boolean agregarTecnico(Tecnico tec) {
if (equipo.contains(tec)) {
System.out.println("Este Técnico ya forma parte del Equipo");
return false;
}
else {
equipo.add(tec);
System.out.println("Técnico añadido al Equipo");
return true;
}
}

@Override
public String toString() {
StringBuilder resumen = new StringBuilder();
resumen.append("\n\tDATOS LIDER");
resumen.append("\nID: " + id);
resumen.append(", Nombre: " + nombre);
resumen.append("\n\tEQUIPO TECNICO");
for (Tecnico tec: equipo)
resumen.append("\n- " + tec.getNombre());

return resumen.toString();
}

}

Luego, además de los Contratos y sus subclases, tenemos la clase Proyecto.
Código: [Seleccionar]
public class Proyecto {

private String id;
private String nombre;
private Lider lider;
private LocalDate fechaInicio;
private LocalDate fechaFin;


public Proyecto(String id, String nombre, Lider lider) {
this.id = id;
this.nombre = nombre;
this.lider = lider;
fechaInicio = LocalDate.now();
fechaFin = null;
}

public String getId() {
return id;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public Lider getLider() {
return lider;
}

public void setLider(Lider lider) {
this.lider = lider;
}

public void finalizarProyecto() {
fechaFin = LocalDate.now();
}

public boolean estaFinalizado() {
return fechaFin != null;
}

@Override
public String toString() {
StringBuilder resumen = new StringBuilder();
resumen.append("\n\tPROYECTO #" + id);
resumen.append("\nNombre: " + nombre);
resumen.append("\nFecha Inicio: " + fechaInicio.toString());
resumen.append("\tFecha Fin: " + (estaFinalizado()?fechaFin.toString():"ACTIVO"));
resumen.append(lider.toString());

return resumen.toString();
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Proyecto) {
Proyecto otroProyecto = (Proyecto) obj;
return id.equals(otroProyecto.id);
}
else
return false;
}
}

Así que nuestro programa ha de gestionar Contratos y Proyectos, con una serie de menús y con la posibilidad de guardar/recuperar datos en disco.

Bien, aquí ya sí que hemos tomado caminos distintos tú y yo.

En mi caso he pensado en crear clases específicas para la gestión de cada cosa.
Una clase GestionContratos, con un ArrayList de contratos y con todos los métodos necesarios para su gestión.
No la he terminado, pero ya da una idea de la estructura que le voy a dar:
Código: [Seleccionar]
public class GestorContratos implements Serializable {

private ArrayList<Contrato> contratos;

public GestorContratos() {
contratos = new ArrayList<Contrato>();
}

public void registrarConsultor() {
Consultor cons = nuevoConsultor();
if (contratos.contains(cons))
System.out.println("Ya existe un Contrato con el ID: " + cons.getId());
else {
contratos.add(cons);
System.out.println("Consultor registrado");
}
}

public void registrarProgramador() {
Programador prog = nuevoProgramador();
if (contratos.contains(prog))
System.out.println("Ya existe un Contrato con el ID: " + prog.getId());
else {
contratos.add(prog);
System.out.println("Programador registrado");
}
}

public void finalizarContrato() {
Scanner teclado = new Scanner(System.in);
System.out.print("ID del contrato: ");
String id = teclado.nextLine();
boolean encontrado = false;
for (Contrato cont: contratos)
if (cont.getId().equals(id)) {
cont.darDeBaja();
encontrado = true;
}

if (encontrado)
System.out.println("Contrato finalizado con exito");
else
System.out.println("No se encuentra Contrato con el ID: " + id);

}

public void listarContratosActivos() {
System.out.println("\n\tCONTRACTOS ACTIVOS\n");
for (Contrato cont: contratos)
if (cont.fechaFin == null)
System.out.println(cont);
}

private Consultor nuevoConsultor() {
Scanner teclado = new Scanner(System.in);
System.out.print("Id: ");
String id = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Salario: ");
double salario = Double.parseDouble(teclado.nextLine());
System.out.print("Labor en la empresa: ");
String labor = teclado.nextLine();

return new Consultor(id, nombre, salario, labor);
}

private Programador nuevoProgramador() {
Scanner teclado = new Scanner(System.in);
System.out.print("Id: ");
String id = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Salario: ");
double salario = Double.parseDouble(teclado.nextLine());
System.out.print("Lenguaje programación: ");
String lenguaje = teclado.nextLine();

return new Programador(id, nombre, salario, lenguaje);
}
}

Y una clase similar, para la gestión de proyectos.
Esta ni siquiera la he empezado, pero su estructura será análoga a la anterior:
Código: [Seleccionar]
public class GestorProyectos implements Serializable {

private ArrayList<Proyecto> proyectos;

public GestorProyectos() {
proyectos = new ArrayList<Proyecto>();
}

/*
* Faltan todos los métodos necesarios para gestionar proyectos
*/
}

Estos dos gestores, puesto que contienen los ArrayList, serán los que nos interesen poder guardar en disco.
Y no solo hay que guardarlos a ellos, también hay que guardar al Lider que ha sido nombrado como director general de la empresa.
Para facilitar el guardado de todo esto, he creado otra clase donde agrupo estos tres elementos con el único propósito de luego poder guardarlo todo en disco como un único objeto.
Así que a priori, no tendrá métodos ni nada. Básicamente es una especie de "contenedor".
La he llamado RecursosHumanos.
Fíjate que el director se lo paso por constructor, esto es porque dicho Lider lo construiremos desde otra clase.
Código: [Seleccionar]
public class RecursosHumanos implements Serializable {

GestorContratos contratos;
GestorProyectos proyectos;
final Lider director;

public RecursosHumanos(Lider director) {
contratos = new GestorContratos();
proyectos = new GestorProyectos();
this.director = director;
}

}

Y ya por último, tendría la clase principal, con un método main para poner en marcha la aplicación, y será aquí donde se mostrarán distintos menús, se pedirán entradas por teclado, se le pedirá a las clases de gestión que hagan una cosa o la otra y también se controlará la persistencia de los datos.

Al iniciarse la aplicación, lo que hará es buscar el archivo de datos guardados y recuperarlo, por lo que obtendremos un objeto RecursosHumanos con el director general y los gestores(y sus ArrayList)

Si no lo encuentra, o bien no consigue recuperar los datos que contiene, se creará un nuevo Director General y los ArrayList se inicializarán sin datos.

Esta clase tampoco la he terminado, pero tiene suficiente código para ver como se van a estructurar los menús, como llamamos al objeto RecursosHumanos para acceder a sus gestores y sobre todo vemos como se guarda y se recupera en disco.
Código: [Seleccionar]
public final class Empresa {

private static Scanner teclado = new Scanner(System.in);
private static RecursosHumanos RRHH;

public static void main(String[] args) {

File fichero = new File("d:/empresa.dat");

if (fichero.exists()) {
try {
ObjectInputStream lector = new ObjectInputStream(new FileInputStream(fichero));
RRHH = (RecursosHumanos) lector.readObject();
lector.close();
} catch (Exception e) {
System.out.println("Error recuperando datos de empresa. Se generará una nueva.\n");
RRHH = new RecursosHumanos(crearDirector());
}
}
else //No hay datos de Empresa guardados
RRHH = new RecursosHumanos(crearDirector());

menuPrincipal();

}

private static Lider crearDirector() {
System.out.println("Indique a continuación los datos del Técnico que será Dir. General de la Empresa");
System.out.print("Id: ");
String id = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Salario: ");
double salario = Double.parseDouble(teclado.nextLine());
return new Lider(id, nombre, salario);
}

private static void menuPrincipal() {
int opcion = 0;
while(opcion != 5) {
System.out.println("\n\n\t\tMENU PRINCIPAL");
System.out.println("\t\t---- ---------\n");
System.out.println("[1] -- Gestion Contratos");
System.out.println("[2] -- Gestion Nominas");
System.out.println("[3] -- Gestion Proyectos");
System.out.println("[4] -- Guardar Datos");
System.out.println("[5] -- TERMINAR PROGRAMA");
System.out.print("Opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
menuContratos();
break;
case 2:
//menuNominas();
break;
case 3:
//menuProyectos();
break;
case 4:
guardarDatos();
break;
case 5:
System.out.println("\n\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opcion equivocada");
}
}
}

private static void menuContratos() {
int opcion = 0;
while (opcion != 8) {
System.out.println("\n\n\t\tGESTION CONTRATOS");
System.out.println("\t\t------- ---------\n");
System.out.println("[1] -- Nuevo Contrato: Consultor");
System.out.println("[2] -- Nuevo Contrato: Programador");
System.out.println("[3] -- Dar de baja un Contrato");
System.out.println("[4] -- Listar Contratos activos");
System.out.println("[5] -- Listar Contratos finalizados");
System.out.println("[6] -- Listar Estructura Jerárquica");
System.out.println("[7] -- Mostrar datos de un Lider");
System.out.println("[8] -- Volver a Menú Principal");
System.out.print("Opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
RRHH.contratos.registrarConsultor();
break;
case 2:
RRHH.contratos.registrarProgramador();
break;
case 3:
RRHH.contratos.finalizarContrato();
break;
case 4:
RRHH.contratos.listarContratosActivos();
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
//Opcion para volver al menu principal, nada que hacer aquí
break;
default:
System.out.println("Opcion equivocada");
}
}
}

private static void guardarDatos() {
File fichero = new File("d:/empresa.dat");
try {
if (!fichero.exists())
fichero.createNewFile();

ObjectOutputStream escritor = new ObjectOutputStream(new FileOutputStream(fichero));
escritor.writeObject(RRHH);
escritor.close();
} catch (Exception e) {
System.out.println("No ha sido posible guardar los datos.\n" + e.getMessage());
e.printStackTrace();
}
}

}


En tu caso parece que has tirado por caminos más complejos.
Parece que los menús quieres tratarlos también como objetos, en lugar de hacer simples métodos.
Aunque lo cierto es que es un camino interesante, quizás esa complejidad luego proporcione alguna ventaja..., no lo se...

Y tu forma de guardar/recuperar datos si que me parece complicada en exceso.
Para salvar los datos también haces una clase, que hereda de la clase menus (¿por qué una "acción de guardar" es un "menú"?) y además implementa la interfaz Serializable, lo cuál es innecesario porque no creo que vayas a guardar en disco un objeto Salvar_Datos

La interfaz Serializable es para las clases que van a ser guardados en disco.

Y por otro lado, no TODO tiene por qué ser una clase.
Las clases normalmente se usan para modelar una entidad o un concepto: un contrato, un proyecto, un perro, una persona, una escuela, un hotel, una factura, un teatro, etc...

Acciones como mostrar un menú o guardar datos en disco, en realidad son funcionalidades y pueden resolverse mediante métodos (que por eso también se le llaman "funciones") escritos en la clase principal o tal vez en alguna otra clase.

Pueden resolverse creando clases, por supuesto, pero luego puede ser más difícil buscar la manera de encajarlos en el proyecto y que se comuniquen con el resto de clases que intervienen.

En fin, revisa el camino que yo he tomado. Decide tú si te parece mejor, o si quizás te da alguna inspiración para lograr resolver mejor tu camino.
Insisto en que no he terminado el programa, así que luego pueden salir errores o necesidad de cambiar algo de lo que ya tengo hecho.
Pero en esencia, el programa ya ha quedado estructurado.

Pregunta lo que no haya quedado claro.
Un saludo.

276
OK, aunque no era necesario hacerlo con los dos tipos de while.
Y ya que se hace, mejor haber cambiado el texto de cuando se usa el do while para adecuarlo a lo que pide el enunciado:

Citar
        //with do..while
       
        int contador = 0;
        do{
           System.out.println ("Contando..."+ (contador+1) + ": " + palabra.substring (i, i+1));
           contador +=1;
        }while (palabra.length()>contador);

Mejor así:
Citar
        //with do..while
       
        int contador = 0;
        do{
           System.out.println ("Letra " + (contador+1) + ": " + palabra.substring (i, i+1));
           contador +=1;
        }while (palabra.length()>contador);

277
Los getters/ setters están asociados a cuando creamos una clase con atributos que va a representar algún tipo de entidad.

Una clase Persona, con nombre y edad, por ejemplo..
Una clase Coche, con asientos y cilindrada.
Una clase Fraccion, con numerador y denominador..
etc...

En estos casos, sí se usan getter/setter para acceder/modificar el valor de esos atributos.


Pero si la clase que vamos a crear es como en este ejercicio, simplemente para ejecutar una tarea y no para crear objetos que representen alguna entidad, entonces los getter/setter no son necesarios.

278
Mmmhh..
NumberFormat sirve para dar formato a los valores, o sea, para indicar como queremos que se muestren.
Pero no es un sistema de validación como tal.

Si quieres validar ese campo, en el ActionListener de ese botón LEER puedes poner validaciones antes de aceptar el valor de dicho campo y trabajar con él.
Por ejemplo

Código: [Seleccionar]
if (campo.isBlank()) //Comprobamos campo no está vacío
    JOptionPane.showMessageDialog(null, "El campo no puede estar vacío");
else {
    String texto = campo.getText();
    //Comprobamos tiene dos caracteres, para poder crear un valor de dos enteros
    if (texto.length() != 2)
        JOptionPane.showMessageDialog(null, "El campo ha de tener dos caracteres");
    else {
        try {
            //Intentamos convertir el valor del campo a un Integer, si falla, se lanzará excepción
            Integer valor = Integer.parseInt(texto);
            //El parseo ha funcionado, el valor es correcto.
            /*
            * Aquí vendría el código para trabajar con ese valor ya validado....
            */
        }
        catch(NumberFormatException ex) { //Aquí capturamos excepción para cuando falle el parseo a Integer
            JOptionPane.showMessageDialog(null, "El campo ha de tener un valor numérico");
        }
    }
}

Como digo, es un ejemplo. Intenta adaptarlo a tu código y a las necesidades de tu programa.
Saludos.

279
El método startsWith() pertenece a la clase String, por tanto, se puede invocar directamente desde el objeto donde hemos recogido la palabra introducida por teclado.

Código: [Seleccionar]
        if (palabra.startsWith("a"))
        System.out.println(" y comienza por \"a\"");
        else
        System.out.println(" y no comienza por \"a\"");

Como puedes ver, el argumento que le proporcionamos a ese método es otro String, en este caso un "a", ya que es la letra que queremos comprobar si se encuentra al comienzo de la palabra o no.


Entonces, si ponemos todo esto junto al resto del código, podemos construir una sola oración en pantalla si donde comprobamos las longitudes usamos print() en lugar de println().
Código: [Seleccionar]
public class CU00657B {

public static void main(String[] args) {

Scanner entradaEscaner = new Scanner(System.in);
       
        System.out.println("Introduzca una palabra");
       
        String palabra = entradaEscaner.nextLine();
       
        if (palabra.length() < 5 ){
            System.out.print("La cadena introducida tiene menos de 5 caracteres");
        } else if (palabra.length() >= 5 &&  palabra.length() <= 15){
            System.out.print("La cadena introducida tiene entre 5 y 15 caracteres");
        } else if (palabra.length() > 15 ) {
            System.out.print("La cadena introducida tiene más de 15 caracteres");
        }
       
        if (palabra.startsWith("a"))
        System.out.println(" y comienza por \"a\"");
        else
        System.out.println(" y no comienza por \"a\"");
       
        entradaEscaner.close();
}
}

En pantalla veremos que se construye una sola oración, y se muestran las comillas "" gracias a que usamos el backlash
Citar
Introduzca una palabra
avioneta
La cadena introducida tiene entre 5 y 15 caracteres y comienza por "a"


Por cierto, un último comentario.
En los if else donde comprobamos la longitud de la cadena, están correctísimos y funcionan perfectamente tal cuál están escritos.

Pero hay una redundancia, la que señalo en rojo:
Citar
        if (palabra.length() < 5 ){
            System.out.print("La cadena introducida tiene menos de 5 caracteres");
        } else if (palabra.length() >= 5 &&  palabra.length() <= 15){
            System.out.print("La cadena introducida tiene entre 5 y 15 caracteres");
        } else if (palabra.length() > 15 ) {
            System.out.print("La cadena introducida tiene más de 15 caracteres");
        }
No es necesario preguntar si la cadena es mayor o igual a 15, porque anteriormente ya se ha preguntado por todas las otras posibilidades posibles (valga la redundancia)

Es decir, si ya sabemos que la cadena NO es menor de 5 caracteres, ni tampoco es menor o igual de 15 caracteres, ya la única posibilidad que nos queda es que sea mayor de 15.

Es decir, podemos "ahorrarnos" en el código esa última pregunta.
Si se pone no pasa nada, es correcto. Pero en programación es habitual acabar desarrollando una obsesión por el ahorro je je..

Citar
        if (palabra.length() < 5 ){
            System.out.print("La cadena introducida tiene menos de 5 caracteres");
        } else if (palabra.length() >= 5 &&  palabra.length() <= 15){
            System.out.print("La cadena introducida tiene entre 5 y 15 caracteres");
        } else { //La única posibilidad es que sea mayor de 15
            System.out.print("La cadena introducida tiene más de 15 caracteres");
        }

Un saludo.

280
Lo más "difícil" es encontrar la forma óptima de comunicar los objetos de unas clases con otras.
- "Donde pongo este ArrayList, que ha de recibir datos de los campos de texto de una clase JPanel, cuando se pulse el botón de otra clase JPanel y luego enviarlos a una tabla que está en otra clase..."

Pero ya hemos visto que se pueden poner referencias allá donde necesitemos.
Si hay tres o cuatro clases JPanel que necesitan interactuar con un objeto declarado en la clase principal, pues a esos JPanel les ponemos un atributo que haga referencia a ese objeto y listo.
Luego esa referencia se la hacemos llegar por constructor, o incluso por un método setter si hace falta.

Porque eso no va a implicar que hayan cuatro objetos distintos, solo habrá uno, pero con varias referencias apuntando hacia el mismo objeto, para que todo el que lo necesite pueda trabajar con él.

Un saludo.


Páginas: 1 ... 9 10 11 12 13 [14] 15 16 17 18 19 ... 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".