domingo, 8 de julio de 2018

Tutorial Java 29

Swing - JLabel

Veamos la segunda componente de la librería swing llamada JLabel.
La clase JLabel nos permite mostrar básicamente un texto.

Problema 1:

Confeccionar una ventana que muestre el nombre de un programa en la parte superior y su número de versión en la parte inferior. No permitir modificar el tamaño de la ventana en tiempo de ejecución.
JLabel

Programa:

import javax.swing.*;
public class Formulario extends JFrame {
    private JLabel label1,label2;
    public Formulario() {
        setLayout(null);
        label1=new JLabel("Sistema de Facturación.");
        label1.setBounds(10,20,300,30);
        add(label1);
        label2=new JLabel("Vesion 1.0");
        label2.setBounds(10,100,100,30);
        add(label2);
    }
    
    public static void main(String[] ar) {
        Formulario formulario1=new Formulario();
        formulario1.setBounds(0,0,300,200);
        formulario1.setResizable(false);
        formulario1.setVisible(true);
    }
}
Importamos el paquete javax.swing donde se encuentran definidas las clase JFrame y JLabel:
import javax.swing.*;
Heredamos de la clase de JFrame:
public class Formulario extends JFrame {
Definimos dos atributos de la clase JLabel:
    private JLabel label1,label2;
En el constructor creamos las dos JLabel y las ubicamos llamando al método setBounds, no hay que olvidar de llamar al método add que añade la JLabel al JFrame:
    public Formulario() {
        setLayout(null);
        label1=new JLabel("Sistema de Facturación.");
        label1.setBounds(10,20,300,30);
        add(label1);
        label2=new JLabel("Vesion 1.0");
        label2.setBounds(10,100,100,30);
        add(label2);
    }
Por último en la main creamos un objeto de la clase que acabamos de codificar, llamamos al setBounds para ubicar y dar tamaño al JFrame, llamamos al método setResizable pasando el valor false para no permitir modificar el tamaño del JFrame en tiempo de ejecución y finalmente llamamos al método setVisible para que se visualice el JFrame:
    public static void main(String[] ar) {
        Formulario formulario1=new Formulario();
        formulario1.setBounds(0,0,300,200);
        formulario1.setResizable(false);
        formulario1.setVisible(true);
    }

 

Tutorial Java 28

Swing - JFrame

La componente básica que requerimos cada vez que implementamos una interfaz visual con la libraría Swing es la clase JFrame. Esta clase encapsula una Ventana clásica de cualquier sistema operativo con entorno gráfico (Windows, OS X, Linux etc.)
Hemos dicho que esta clase se encuentra en el paquete javax.swing y como generalmente utilizamos varias clases de este paquete luego para importarla utilizamos la sintaxis:
import javax.swing.*;
Podemos hacer una aplicación mínima con la clase JFrame:
import javax.swing.JFrame;
public class Formulario {
    public static void main(String[] ar) {
        JFrame f=new JFrame();
        f.setBounds(10,10,300,200);
        f.setVisible(true);
    }
}
Como vemos importamos la clase JFrame del paquete javax.swing:
import javax.swing.JFrame;
y luego en la main definimos y creamos un objeto de la clase JFrame (llamando luego a los métodos setBounds y setVisible):
    public static void main(String[] ar) {
        JFrame f=new JFrame();
        f.setBounds(10,10,300,200);
        f.setVisible(true);
    }
Pero esta forma de trabajar con la clase JFrame es de poca utilidad ya que rara vez necesitemos implementar una aplicación que muestre una ventana vacía.
Lo más correcto es plantear una clase que herede de la clase JFrame y extienda sus responsabilidades agregando botones, etiquetas, editores de línea etc.
Entonces la estructura básica que emplearemos para crear una interfaz visual será:

Programa:

import javax.swing.*;
public class Formulario extends JFrame{
    public Formulario() {
        setLayout(null);
    }

    public static void main(String[] ar) {
        Formulario formulario1=new Formulario();
        formulario1.setBounds(10,20,400,300);
        formulario1.setVisible(true);
    }
}
Importamos el paquete donde se encuentra la clase JFrame:
import javax.swing.*;
Planteamos una clase que herede de la clase JFrame:
public class Formulario extends JFrame{
En el constructor indicamos que ubicaremos los controles visuales con coordenadas absolutas mediante la desactivación del Layout heredado (más adelante veremos otras formas de ubicar los controles visuales dentro del JFrame):
    public Formulario() {
        setLayout(null);
    }
En la main creamos un objeto de la clase y llamamos a los métodos setBounds y setVisible:
    public static void main(String[] ar) {
        Formulario formulario1=new Formulario();
        formulario1.setBounds(10,20,400,300);
        formulario1.setVisible(true);
    }
El método setBounds ubica el JFrame (la ventana) en la columna 10, fila 20 con un ancho de 400 píxeles y un alto de 300.
Debemos llamar al método setVisible y pasarle el valor true para que se haga visible la ventana.

 

Tutorial Java 27

Interfaces visuales (componentes Swing)

Hasta ahora hemos resuelto todos los algoritmos haciendo las salidas a través de una consola en modo texto. La realidad que es muy común la necesidad de hacer la entrada y salida de datos mediante una interfaz más amigables con el usuario.
En Java existen varias librerías de clase para implementar interfaces visuales. Utilizaremos las componentes Swing.

Problema 1:

Confeccionar el programa "Hola Mundo" utilizando una interfaz gráfica de usuario.

Programa:

import javax.swing.*;
public class Formulario extends JFrame{
    private JLabel label1;
    public Formulario() {
        setLayout(null);
        label1=new JLabel("Hola Mundo.");
        label1.setBounds(10,20,200,30);
        add(label1);
    }
    
    public static void main(String[] ar) {
        Formulario formulario1=new Formulario();
        formulario1.setBounds(10,10,400,300);
        formulario1.setVisible(true);
    }
}
Hasta ahora habíamos utilizado la clase Scanner para hacer la entrada de datos por teclado. Dicha clase debemos importarla en nuestro programa con la sintaxis:
import java.util.Scanner;
Otra sintaxis para importarla es:
import java.util.*;
Si disponemos un * indicamos que importe todas las clases del paquete java.util.
Ahora bien las componentes Swing hay que importarlas del paquete javax.swing. Cuando debemos importar varias componentes de un paquete es más conveniente utilizar el asterisco que indicar cada clase a importar:
import javax.swing.JFrame;
import javax.swing.JLabel;
En lugar de las dos líneas anteriores es mejor utilizar la sintaxis:
import javax.swing.*;
La clase JFrame encapsula el concepto de una ventana. Luego para implementar una aplicación que muestre una ventana debemos plantear una clase que herede de la clase JFrame:
public class Formulario extends JFrame{
Con la sintaxis anterior estamos indicando que que la clase Formulario hereda todos los métodos y propiedades de la clase JFrame.
Para mostrar un texto dentro de una ventana necesitamos requerir la colaboración de la clase JLabel (que tiene por objetivo mostrar un texto dentro de un JFrame)
Definimos luego como atributo de la clase un objeto de la clase JLabel:
    private JLabel label1;
En el constructor de la clase llamamos al método heredado de la clase JFrame llamado setLayout y le pasamos como parámetro un valor null, con esto estamos informándole a la clase JFrame que utilizaremos posicionamiento absoluto para los controles visuales dentros del JFrame.
    public Formulario() {
        setLayout(null);
Luego tenemos que crear el objeto de la clase JLabel y pasarle como parámetro al constructor el texto a mostrar:
        label1=new JLabel("Hola Mundo.");
Ubicamos al objeto de la clase JLabel llamando al método setBounds, este requiere como parámetros la columna, fila, ancho y alto del JLabel. Finalmente llamamos al método add (metodo heredado de la clase JFrame) que tiene como objetivo añadir el control JLabel al control JFrame.
        label1=new JLabel("Hola Mundo.");
        label1.setBounds(10,20,200,30);
        add(label1);
    }
Finalmente debemos codificar la main donde creamos un objeto de la clase Formulario, llamamos al método setBounds para ubicar y dar tamaño al control y mediante el método setVisible hacemos visible el JFrame:
    public static void main(String[] ar) {
        Formulario formulario1=new Formulario();
        formulario1.setBounds(10,10,400,300);
        formulario1.setVisible(true);
    }
Cuando ejecutamos nuestro proyecto tenemos como resultado una ventana similar a esta:
JFrame y JLabel

 

Tutorial Java 26

Herencia

Vimos en el concepto anterior que dos clases pueden estar relacionadas por la colaboración. Ahora veremos otro tipo de relaciones entre clases que es la Herencia.
La herencia significa que se pueden crear nuevas clases partiendo de clases existentes, que tendrá todas los atributos y los métodos de su 'superclase' o 'clase padre' y además se le podrán añadir otros atributos y métodos propios.

clase padre

Clase de la que desciende o deriva una clase. Las clases hijas (descendientes) heredan (incorporan) automáticamente los atributos y métodos de la la clase padre.

Subclase

Clase desciendiente de otra. Hereda automáticamente los atributos y métodos de su superclase. Es una especialización de otra clase. Admiten la definición de nuevos atributos y métodos para aumentar la especialización de la clase.
Veamos algunos ejemplos teóricos de herencia:
1) Imaginemos la clase Vehículo. Qué clases podrían derivar de ella?
                            Vehiculo

   Colectivo                Moto                    Auto
                             
                                             FordK        Renault 9
Siempre hacia abajo en la jerarquía hay una especialización (las subclases añaden nuevos atributos y métodos.
2) Imaginemos la clase Software. Qué clases podrían derivar de ella?
                                           Software

             DeAplicacion                                        DeBase

ProcesadorTexto       PlanillaDeCalculo                          SistemaOperativo

Word   WordPerfect    Excel     Lotus123                         Linux    Windows       
El primer tipo de relación que habíamos visto entre dos clases, es la de colaboración. Recordemos que es cuando una clase contiene un objeto de otra clase como atributo.
Cuando la relación entre dos clases es del tipo "...tiene un..." o "...es parte de...", no debemos implementar herencia. Estamos frente a una relación de colaboración de clases no de herencia.
Si tenemos una ClaseA y otra ClaseB y notamos que entre ellas existe una relacion de tipo "... tiene un...", no debe implementarse herencia sino declarar en la clase ClaseA un atributo de la clase ClaseB.

Por ejemplo: tenemos una clase Auto, una clase Rueda y una clase Volante. Vemos que la relación entre ellas es: Auto "...tiene 4..." Rueda, Volante "...es parte de..." Auto; pero la clase Auto no debe derivar de Rueda ni Volante de Auto porque la relación no es de tipo-subtipo sino de colaboración. Debemos declarar en la clase Auto 4 atributos de tipo Rueda y 1 de tipo Volante.
Luego si vemos que dos clase responden a la pregunta ClaseA "..es un.." ClaseB es posible que haya una relación de herencia.
Por ejemplo:
Auto "es un" Vehiculo
Circulo "es una" Figura
Mouse "es un" DispositivoEntrada
Suma "es una" Operacion

Problema 1:

Ahora plantearemos el primer problema utilizando herencia. Supongamos que necesitamos implementar dos clases que llamaremos Suma y Resta. Cada clase tiene como atributo valor1, valor2 y resultado. Los métodos a definir son cargar1 (que inicializa el atributo valor1), carga2 (que inicializa el atributo valor2), operar (que en el caso de la clase "Suma" suma los dos atributos y en el caso de la clase "Resta" hace la diferencia entre valor1 y valor2, y otro método mostrarResultado.
Si analizamos ambas clases encontramos que muchos atributos y métodos son idénticos. En estos casos es bueno definir una clase padre que agrupe dichos atributos y responsabilidades comunes.

La relación de herencia que podemos disponer para este problema es:
                                        Operacion

                        Suma                              Resta
Solamente el método operar es distinto para las clases Suma y Resta (esto hace que no lo podamos disponer en la clase Operacion), luego los métodos cargar1, cargar2 y mostrarResultado son idénticos a las dos clases, esto hace que podamos disponerlos en la clase Operacion. Lo mismo los atributos valor1, valor2 y resultado se definirán en la clase padre Operacion.
Crear un proyecto y luego crear cuatro clases llamadas: Operacion, Suma, Resta y Prueba

Programa:

import java.util.Scanner;
public class Operacion {
    protected Scanner teclado;
    protected int valor1;
    protected int valor2;
    protected int resultado;
    public Operacion() {
        teclado=new Scanner(System.in);
    }
    
    public void cargar1() {
        System.out.print("Ingrese el primer valor:");
        valor1=teclado.nextInt();        
    }
    
    public void cargar2() {
        System.out.print("Ingrese el segundo valor:");
        valor2=teclado.nextInt();
    }
    
    public void mostrarResultado() {
        System.out.println(resultado);
    }
}




public class Suma extends Operacion{
    void operar() {
        resultado=valor1+valor2;
    }
}




public class Resta extends Operacion {
    public void operar(){
        resultado=valor1-valor2;
    }
}


public class Prueba {
    public static void main(String[] ar) {
        Suma suma1=new Suma();
        suma1.cargar1();
        suma1.cargar2();
        suma1.operar();
        System.out.print("El resultado de la suma es:");
        suma1.mostrarResultado();
        Resta resta1=new Resta();
        resta1.cargar1();
        resta1.cargar2();
        resta1.operar();
        System.out.print("El resultado de la resta es:");        
        resta1.mostrarResultado();
    }
}
La clase Operación define los cuatro atributos:
import java.util.Scanner;
public class Operacion {
    protected Scanner teclado;
    protected int valor1;
    protected int valor2;
    protected int resultado;
Ya veremos que definimos los atributos con este nuevo modificador de acceso (protected) para que la subclase tenga acceso a dichos atributos. Si los definimos private las subclases no pueden acceder a dichos atributos.
Los métodos de la clase Operacion son:
    public Operacion() {
        teclado=new Scanner(System.in);
    }
    
    public void cargar1() {
        System.out.print("Ingrese el primer valor:");
        valor1=teclado.nextInt();        
    }
    
    public void cargar2() {
        System.out.print("Ingrese el segundo valor:");
        valor2=teclado.nextInt();
    }
    
    public void mostrarResultado() {
        System.out.println(resultado);
    }
Ahora veamos como es la sintaxis para indicar que una clase hereda de otra:
public class Suma extends Operacion{
Utilizamos la palabra clave extends y seguidamente el nombre de la clase padre (con esto estamos indicando que todos los métodos y atributos de la clase Operación son también métodos de la clase Suma.
Luego la característica que añade la clase Suma es el siguiente método:
    void operar() {
        resultado=valor1+valor2;
    }
El método operar puede acceder a los atributos heredados (siempre y cuando los mismos se declaren protected, en caso que sean private si bien lo hereda de la clase padre solo los pueden modificar métodos de dicha clase padre.
Ahora podemos decir que la clase Suma tiene cinco métodos (cuatro heredados y uno propio) y 3 atributos (todos heredados)

Luego en otra clase creamos un objeto de la clase Suma:
public class Prueba {
    public static void main(String[] ar) {
        Suma suma1=new Suma();
        suma1.cargar1();
        suma1.cargar2();
        suma1.operar();
        System.out.print("El resultado de la suma es:");
        suma1.mostrarResultado();
        Resta resta1=new Resta();
        resta1.cargar1();
        resta1.cargar2();
        resta1.operar();
        System.out.print("El resultado de la resta es:");        
        resta1.mostrarResultado();
    }
}
Podemos llamar tanto al método propio de la clase Suma "operar()" como a los métodos heredados. Quien utilice la clase Suma solo debe conocer que métodos públicos tiene (independientemente que pertenezcan a la clase Suma o a una clase superior)
La lógica es similar para declarar la clase Resta.
La clase Operación agrupa en este caso un conjunto de atributos y métodos comunes a un conjunto de subclases (Suma, Resta). No tiene sentido definir objetos de la clase Operacion.
El planteo de jerarquías de clases es una tarea compleja que requiere un perfecto entendimiento de todas las clases que intervienen en un problema, cuales son sus atributos y responsabilidades.

Fuente:

 

domingo, 3 de junio de 2018

Tutorial Java 25

Colaboración de clases

Normalmente un problema resuelto con la metodología de programación orientada a objetos no interviene una sola clase, sino que hay muchas clases que interactúan y se comunican.
Plantearemos un problema separando las actividades en dos clases.

Problema 1:

Un banco tiene 3 clientes que pueden hacer depósitos y extracciones. También el banco requiere que al final del día calcule la cantidad de dinero que hay depositada.
Lo primero que hacemos es identificar las clases:
Podemos identificar la clase Cliente y la clase Banco.
Luego debemos definir los atributos y los métodos de cada clase:
Cliente  
    atributos
        nombre
        monto
    métodos
        constructor
        depositar
        extraer
        retornarMonto

Banco
    atributos
        3 Cliente (3 objetos de la clase Cliente)
        1 Scanner (Para poder hacer la entrada de datos por teclado)
    métodos
        constructor
        operar
        depositosTotales
Creamos un proyecto en Eclipse llamado: Proyecto1 y dentro del proyecto creamos dos clases llamadas: Cliente y Banco.

Programa:

public class Cliente {
    private String nombre;
    private int monto;
    
    public Cliente(String nom) {
        nombre=nom;
        monto=0;
    }
    
    public void depositar(int m) {
        monto=monto+m;
    }
    
    public void extraer(int m) {
        monto=monto-m;
    }
    
    public int retornarMonto() {
        return monto;
    }
    
    public void imprimir() {
        System.out.println(nombre+" tiene depositado la suma de "+monto);
    }
}





public class Banco {
    private Cliente cliente1,cliente2,cliente3;
 
    public Banco() {
        cliente1=new Cliente("Juan");
        cliente2=new Cliente("Ana");
        cliente3=new Cliente("Pedro"); 
    }

    public void operar() {
        cliente1.depositar (100);
        cliente2.depositar (150);
        cliente3.depositar (200);
        cliente3.extraer (150);
    }
 
    public void depositosTotales ()
    {
        int t = cliente1.retornarMonto () + cliente2.retornarMonto () + cliente3.retornarMonto ();
        System.out.println ("El total de dinero en el banco es:" + t);
        cliente1.imprimir();
        cliente2.imprimir();
        cliente3.imprimir();
    }

    public static void main(String[] ar) {
        Banco banco1=new Banco();
        banco1.operar();
        banco1.depositosTotales();
    }
}
Analicemos la implementación del problema.
Los atributos de una clase normalmente son privados para que no se tenga acceso directamente desde otra clase, los atributos son modificados por los métodos de la misma clase:
    private String nombre;
    private int monto;
El constructor recibe como parámetro el nombre del cliente y lo almacena en el atributo respectivo e inicializa el atributo monto en cero:
    public Cliente(String nom) {
        nombre=nom;
        monto=0;
    }
Los métodos depositar y extraer actualizan el atributo monto con el dinero que llega como parámetro (para simplificar el problema no hemos validado que cuando se extrae dinero el atributo monto quede con un valor negativo):
    public void depositar(int m) {
        monto=monto+m;
    }
    
    public void extraer(int m) {
        monto=monto-m;
    }
El método retornarMonto tiene por objetivo comunicar al Banco la cantidad de dinero que tiene el cliente (recordemos que como el atributo monto es privado de la clase, debemos tener un método que lo retorne):
    public int retornarMonto() {
        return monto;
    }
Por último el método imprimir muestra nombre y el monto de dinero del cliente:
    public void imprimir() {
        System.out.println(nombre+" tiene depositado la suma de "+monto);
    }
Como podemos observar la clase Cliente no tiene función main. Entonces donde definimos objetos de la clase Cliente?
La respuesta a esta pregunta es que en la clase Banco definimos tres objetos de la clase Cliente.
Veamos ahora la clase Banco que requiere la colaboración de la clase Cliente.
Primero definimos tres atributos de tipo Cliente:
public class Banco {
    private Cliente cliente1,cliente2,cliente3;

En le constructor creamos los tres objetos (cada vez que creamos un objeto de la clase Cliente debemos pasar a su constructor el nombre del cliente, recordemos que su monto de depósito se inicializa con cero):
    public Banco() {
        cliente1=new Cliente("Juan");
        cliente2=new Cliente("Ana");
        cliente3=new Cliente("Pedro"); 
    }
El método operar del banco (llamamos a los métodos depositar y extraer de los clientes):
    public void operar() {
        cliente1.depositar (100);
        cliente2.depositar (150);
        cliente3.depositar (200);
        cliente3.extraer (150);
    }
El método depositosTotales obtiene el monto depositado de cada uno de los tres clientes, procede a mostrarlos y llama al método imprimir de cada cliente para poder mostrar el nombre y depósito:
    public void depositosTotales ()
    {
        int t = cliente1.retornarMonto () + cliente2.retornarMonto () + cliente3.retornarMonto ();
        System.out.println ("El total de dinero en el banco es:" + t);
        cliente1.imprimir();
        cliente2.imprimir();
        cliente3.imprimir();
    }
Por último en la main definimos un objeto de la clase Banco (la clase Banco es la clase principal en nuestro problema):
    public static void main(String[] ar) {
        Banco banco1=new Banco();
        banco1.operar();
        banco1.depositosTotales();
    }

Problema 2:

Plantear un programa que permita jugar a los dados. Las reglas de juego son: se tiran tres dados si los tres salen con el mismo valor mostrar un mensaje que "gano", sino "perdió".
Lo primero que hacemos es identificar las clases:
Podemos identificar la clase Dado y la clase JuegoDeDados.
Luego los atributos y los métodos de cada clase:
Dado  
    atributos
        valor
    métodos
        tirar
        imprimir
        retornarValor

JuegoDeDados
    atributos
        3 Dado (3 objetos de la clase Dado)
    métodos
        constructor
        jugar
Creamos un proyecto en Eclipse llamado: Proyecto2 y dentro del proyecto creamos dos clases llamadas: Dado y JuegoDeDados.

Programa:

public class Dado {
    private int valor;
    
    public void tirar() {
        valor=1+(int)(Math.random()*6);
    }
    
    public void imprimir() {
        System.out.println("El valor del dado es:"+valor);
    }
    
    public int retornarValor() {
        return valor;
    }
}




public class JuegoDeDados {
    private Dado dado1,dado2,dado3;
    
    public JuegoDeDados() {
        dado1=new Dado();
        dado2=new Dado();
        dado3=new Dado();         
    }
    
    public void jugar() {
        dado1.tirar();
        dado1.imprimir();
        dado2.tirar();
        dado2.imprimir();
        dado3.tirar();
        dado3.imprimir();
        if (dado1.retornarValor()==dado2.retornarValor() && 
            dado1.retornarValor()==dado3.retornarValor()) {
            System.out.println("Ganó");
        } else {
            System.out.println("Perdió");
        }         
    }
    
    public static void main(String[] ar){
        JuegoDeDados j=new JuegoDeDados();
        j.jugar();
    }
}
La clase dado define el atributo "valor" donde almacenamos un valor aleatorio que representa el número que sale al tirarlo.
public class Dado {
    private int valor;
El método tirar almacena el valor aleatorio (para generar un valor aleatorio utilizamos el método random de la clase Math, el mismo genera un valor real comprendido entre 0 y 1, pero nunca 0 o 1. Puede ser un valor tan pequeño como 0.0001 o tan grando como 0.9999. Luego este valor generado multiplicado por 6 y antecediendo (int) obtenemos la parte entera de dicho producto):
    public void tirar() {
        valor=1+(int)(Math.random()*6);
    }
Como vemos le sumamos uno ya que el producto del valor aleatorio con seis puede generar números enteros entre 0 y 5.
El método imprimir de la clase Dado muestra por pantalla el valor del dado:
    public void imprimir() {
        System.out.println("El valor del dado es:"+valor);
    }
Por último el método que retorna el valor del dado (se utiliza en la otra clase para ver si los tres dados generaron el mismo valor):
    public int retornarValor() {
        return valor;
    }
La clase JuegoDeDatos define tres atributos de la clase Dado (con esto decimos que la clase Dado colabora con la clase JuegoDeDados):
public class JuegoDeDados {
    private Dado dado1,dado2,dado3;
En el constructor procedemos a crear los tres objetos de la clase Dado:
    public JuegoDeDados() {
        dado1=new Dado();
        dado2=new Dado();
        dado3=new Dado();         
    }
En el método jugar llamamos al método tirar de cada dado, pedimos que se imprima el valor generado y finalmente procedemos a verificar si se ganó o no:
    public void jugar() {
        dado1.tirar();
        dado1.imprimir();
        dado2.tirar();
        dado2.imprimir();
        dado3.tirar();
        dado3.imprimir();
        if (dado1.retornarValor()==dado2.retornarValor() && 
            dado1.retornarValor()==dado3.retornarValor()) {
            System.out.println("Ganó");
        } else {
            System.out.println("Perdió");
        }         
    }
En la main creamos solo un objeto de la clase principal (en este caso la clase principal es el JuegoDeDados):
    public static void main(String[] ar){
        JuegoDeDados j=new JuegoDeDados();
        j.jugar();
    }

 

Tutorial Java 24

Clase String

La clase String está orientada a manejar cadenas de caracteres. Hasta este momento hemos utilizado algunos métodos de la clase String (equals, compareTo)
Ahora veremos otro conjunto de métodos de uso común de la clase String:

Métodos

  • boolean equals(String s1)
    
    Como vimos el método equals retorna true si el contenido de caracteres del parámetro s1 es exactamente igual a la cadena de caracteres del objeto que llama al método equals.
  • boolean equalsIgnoreCase(String s1)
    
    El funcionamiento es casi exactamente igual que el método equals con la diferencia que no tiene en cuenta mayúsculas y minúsculas (si comparamos 'Ana' y 'ana' luego el método equalsIgnoreCase retorna true)
  • int compareTo(String s1)
    
    Este método retorna un 0 si el contenido de s1 es exactamente igual al String contenido por el objeto que llama al método compareTo. Retorna un valor >0 si el contenido del String que llama al método compareTo es mayor alfabéticamente al parámetro s1.
  • char charAt(int pos)
    
    Retorna un caracter del String, llega al método la posición del caracter a extraer.
  • int length()
    
    Retorna la cantidad de caracteres almacenados en el String.
  • String substring(int pos1,int pos2)
    
    Retorna un substring a partir de la posición indicada en el parámetro pos1 hasta la posición pos2 sin incluir dicha posición.
  • int indexOf(String s1)
    
    Retorna -1 si el String que le pasamos como parámetro no está contenida en la cadena del objeto que llama al método. En caso que se encuentre contenido el String s1 retorna la posición donde comienza a repetirse.
  • String toUpperCase()
    
    Retorna un String con el contenido convertido todo a mayúsculas.
  • String toLowerCase()
    
    Retorna un String con el contenido convertido todo a minúsculas.

Problema 1:

Confeccionar una clase que solicite el ingreso de dos String y luego emplee los métodos más comunes de la clase String.

Programa:

import java.util.Scanner;
public class Cadena1 {
    public static void main(String[] ar) {
        Scanner teclado=new Scanner(System.in);
        String cad1;
        String cad2;
        System.out.print("Ingrese la primer cadena:");
        cad1=teclado.nextLine();
        System.out.print("Ingrese la segunda cadena:");
        cad2=teclado.nextLine();
        if (cad1.equals(cad2)==true) {
            System.out.println(cad1+" es exactamente igual a "+cad2);
        } else {
            System.out.println(cad1+" no es exactamente igual a "+cad2);        
        }
        if (cad1.equalsIgnoreCase(cad2)==true) {
            System.out.println(cad1+" es igual a "+cad2+" sin tener en cuenta mayúsculas/minúsculas");
        } else {
            System.out.println(cad1+" no es igual a "+cad2+" sin tener en cuenta mayúsculas/minúsculas");        
        }
        if (cad1.compareTo(cad2)==0) {
            System.out.println(cad1+" es exactamente igual a "+cad2);
        } else {
            if (cad1.compareTo(cad2)>0) {
                System.out.println(cad1+ " es mayor alfabéticamente que "+cad2);
            } else {
                System.out.println(cad2+ " es mayor alfabéticamente que "+cad1);            
            }
        }        
        char carac1=cad1.charAt(0);
        System.out.println("El primer caracter de "+cad1+" es "+carac1);
        int largo=cad1.length();
        System.out.println("El largo del String "+cad1+" es "+largo);
        String cad3=cad1.substring(0,3);
        System.out.println("Los primeros tres caracteres de "+cad1+" son "+cad3);
        int posi=cad1.indexOf(cad2);
        if (posi==-1) {
            System.out.println(cad2+" no está contenido en "+cad1);
        } else {
            System.out.println(cad2+" está contenido en "+cad1+" a partir de la posición "+posi);
        }
        System.out.println(cad1+ " convertido a mayúsculas es "+cad1.toUpperCase());
        System.out.println(cad1+ " convertido a minúsculas es "+cad1.toLowerCase());        
    }
}
Para cargar los dos String utilizamos en este caso el método nextLine para permitir ingresar espacios en blanco:
        System.out.print("Ingrese la primer cadena:");
        cad1=teclado.nextLine();
        System.out.print("Ingrese la segunda cadena:");
        cad2=teclado.nextLine();

 

Tutorial Java 23

Constructor de la clase

En Java podemos definir un método que se ejecute inicialmente y en forma automática. Este método se lo llama constructor.
El constructor tiene las siguientes características:
  • Tiene el mismo nombre de la clase.
  • Es el primer método que se ejecuta.
  • Se ejecuta en forma automática.
  • No puede retornar datos.
  • Se ejecuta una única vez.
  • Un constructor tiene por objetivo inicializar atributos.

Problema 1:

Se desea guardar los sueldos de 5 operarios en un vector. Realizar la creación y carga del vector en el constructor.

Programa:

import java.util.Scanner;
public class Operarios {
    private Scanner teclado;
    private int[] sueldos;
 
    public Operarios()
    {
        teclado=new Scanner(System.in);
        sueldos=new int[5];
        for(int f=0;f<5;f++) {
            System.out.print("Ingrese valor de la componente:");
            sueldos[f]=teclado.nextInt();
        } 
    }
 
    public void imprimir() {
        for(int f=0;f<5;f++) {
            System.out.println(sueldos[f]);
        }
    }
 
    public static void main(String[] ar) {
        Operarios op=new Operarios();
        op.imprimir();
    }
}
Como podemos ver es el mismo problema que resolvimos cuando vimos vectores. La diferencia es que hemos sustituido el método cargar con el constructor:
    public Operarios()
    {
        teclado=new Scanner(System.in);
        sueldos=new int[5];
        for(int f=0;f<5;f++) {
            System.out.print("Ingrese valor de la componente:");
            sueldos[f]=teclado.nextInt();
        } 
    }
Como la clase se llama Operarios el constructor tiene el mismo nombre, no disponemos la palabra clave void ya que el constructor no puede retornar datos.
La ventaja de plantear un constructor en lugar de definir un método con cualquier nombre es que se llamará en forma automática cuando se crea un objeto de esta clase:
    public static void main(String[] ar) {
        Operarios op=new Operarios();
Cuando se crea el objeto op se llama al método constructor.
Finalmente llamamos al método imprimir:
        op.imprimir();

Problema 2:

Plantear una clase llamada Alumno y definir como atributos su nombre y su edad. En el constructor realizar la carga de datos. Definir otros dos métodos para imprimir los datos ingresados y un mensaje si es mayor o no de edad (edad >=18)

Programa:

import java.util.Scanner;
public class Alumno {
    private Scanner teclado;
    private String nombre;
    private int edad;
    
    public Alumno() {
        teclado=new Scanner(System.in);
        System.out.print("Ingrese nombre:");
        nombre=teclado.next();
        System.out.print("Ingrese edad:");
        edad=teclado.nextInt();
    }
    
    public void imprimir() {
        System.out.println("Nombre:"+nombre);
        System.out.println("Edad:"+edad);
    }
    
    public void esMayorEdad() {
        if (edad>=18) {
            System.out.print(nombre+" es mayor de edad.");
        } else {
            System.out.print(nombre+" no es mayor de edad.");
        }
    }
    
    public static void main(String[] ar) {
        Alumno alumno1=new Alumno();
        alumno1.imprimir();
        alumno1.esMayorEdad();
    }
}
Declaramos la clase Persona, sus tres atributos y definimos el constructor con el mismo nombre de la clase:
public class Alumno {
    private Scanner teclado;
    private String nombre;
    private int edad;
    
    public Alumno() {
        teclado=new Scanner(System.in);
        System.out.print("Ingrese nombre:");
        nombre=teclado.next();
        System.out.print("Ingrese edad:");
        edad=teclado.nextInt();
    }
En la main el constructor se llama en forma automática cuando creamos un objeto de la clase Alumno:
    public static void main(String[] ar) {
        Alumno alumno1=new Alumno();
Los otros dos métodos deben llamarse por su nombre y en el orden que necesitemos:
        alumno1.imprimir();
        alumno1.esMayorEdad();

 

Tutorial Java 22

Matrices irregulares

Java nos permite crear matrices irregulares. Se dice que una matriz es irregular si la cantidad de elementos de cada fila varía. Luego podemos imaginar una matriz irregular:
matriz irregular
Como podemos ver la fila cero tiene reservado dos espacios, la fila uno reserva cuatro espacios y la última fila reserva espacio para tres componentes.
Para crear la matriz irregular del gráfico:
La declaración es la misma que para matrices regulares:
int [][] mat;
Primero creamos la cantidad de filas dejando vacío el espacio que indica la cantidad de columnas:
mat=new int[3][];
Luego debemos ir creando cada fila de la matriz indicando la cantidad de elementos de la respectiva fila:
mat[0]=new int[2];
mat[1]=new int[4];
mat[2]=new int[3];
Luego la forma para acceder a sus componentes es similar a las matrices regulares, siempre teniendo en cuenta y validando que exista dicha componente:
mat[0][0]=120;
Dará un error si queremos cargar la tercer componente de la fila cero (esto debido a que no existe):
mat[0][2]=230;
Luego si queremos saber la cantidad de filas que tiene la matriz:
Sytem.out.println(mat.length);
Si queremos saber la cantidad de elementos de una determinada fila:
Sytem.out.println("Cantidad de elementos de la fila 0:"+mat[0].length);
Sytem.out.println("Cantidad de elementos de la fila 1:"+mat[1].length);
Sytem.out.println("Cantidad de elementos de la fila 2:"+mat[2].length);

Problema 1:

Confeccionaremos un programa que permita crear una matriz irregular y luego imprimir la matriz en forma completa.

Programa:

import java.util.Scanner;
public class MatrizIrregular1 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        mat=new int[filas][];
        for(int f=0;f<mat.length;f++) {
            System.out.print("Cuantas elementos tiene la fila " + f + ":");
            int elementos=teclado.nextInt();
            mat[f]=new int[elementos];            
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void imprimir() {
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] ar) {
        MatrizIrregular1 ma=new MatrizIrregular1();
        ma.cargar();
        ma.imprimir();
    }   
}
Primero creamos la cantidad de filas que tendrá la matriz (en los corchetes para las columnas no disponemos valor):
        System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        mat=new int[filas][];
Dentro del primer for pedimos que ingrese la cantidad de elementos que tendrá cada fila y utilizamos el operador new nuevamente, pero en este caso se están creando cada fila de la matriz (Java trata a cada fila como un vector):
        for(int f=0;f<mat.length;f++) {
            System.out.print("Cuantas elementos tiene la fila " + f + ":");
            int elementos=teclado.nextInt();
            mat[f]=new int[elementos];            
Dentro del for interno hacemos la carga de las componentes propiamente dicho de la matriz (podemos ir cargando cada fila a medida que las vamos creando):
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
Luego imprimimos la matriz en forma completa teniendo cuidado las condiciones que disponemos en cada for.
El primer for se repite tantas veces como filas tiene la matriz: f<mat.length y
el for interno se repite tantas veces como elementos tiene la fila que estamos procesando c<mat [f].length:
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }

 

Tutorial Java 21

Matrices y vectores paralelos

Dependiendo de la complejidad del problema podemos necesitar el empleo de vectores y matrices paralelos.

Problema 1:

Se tiene la siguiente información:
· Nombres de 4 empleados.
· Ingresos en concepto de sueldo, cobrado por cada empleado, en los últimos 3 meses.
Confeccionar el programa para:
a) Realizar la carga de la información mencionada.
b) Generar un vector que contenga el ingreso acumulado en sueldos en los últimos 3 meses para cada empleado.
c) Mostrar por pantalla el total pagado en sueldos a todos los empleados en los últimos 3 meses
d) Obtener el nombre del empleado que tuvo el mayor ingreso acumulado
vectores y matrices paralelos

Programa:

import java.util.Scanner;
public class Matriz9 {
    private Scanner teclado;
    private String[] empleados;
    private int[][] sueldos;
    private int[] sueldostot;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        empleados=new String[4];
        sueldos=new int[4][3];
        for(int f=0;f<empleados.length;f++){
            System.out.print("Ingrese el nombre del empleado:");
            empleados[f]=teclado.next();
            for(int c=0;c<sueldos[f].length;c++) {
                System.out.print("Ingrese sueldo:");
                sueldos[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void calcularSumaSueldos() {
     sueldostot=new int[4];
        for(int f=0;f<sueldos.length;f++) {
          int suma=0;
          for(int c=0;c<sueldos[f].length;c++) {
              suma=suma+sueldos[f][c];
          }
          sueldostot[f]=suma;
        }
    }
    
    public void imprimirTotalPagado() {
     System.out.println("Total de sueldos pagados por empleado.");
        for(int f=0;f<sueldostot.length;f++) {
            System.out.println(empleados[f]+" - "+sueldostot[f]);
        }
    }
    
    public void empleadoMayorSueldo() {
        int may=sueldostot[0];
        String nom=empleados[0];
        for(int f=0;f<sueldostot.length;f++) {
            if (sueldostot[f]>may) {
                may=sueldostot[f];
                nom=empleados[f];
            }
        }
        System.out.println("El empleado con mayor sueldo es "+ nom + " que tiene un sueldo de "+may);
    }
    
    public static void main(String[] ar){
        Matriz9 ma=new Matriz9();
        ma.cargar();
        ma.calcularSumaSueldos();
        ma.imprimirTotalPagado();
        ma.empleadoMayorSueldo();
    }
}
Para resolver este problema lo primero que hacemos es definir una matriz donde se almacenarán los sueldos mensuales de cada empleado, un vector de tipo String donde almacenaremos los nombre de cada empleado y finalmente definimos un vector paralelo a la matriz donde almacenaremos la suma de cada fila de la matriz:
    private String[] empleados;
    private int[][] sueldos;
    private int[] sueldostot;
En el método de cargar inicializamos el vector con los nombres de los empleados y la matriz paralela donde se almacenan los últimos tres sueldos (previo a cargar procedemos a crear el vector y la matriz):
        empleados=new String[4];
        sueldos=new int[4][3];
        for(int f=0;f<empleados.length;f++){
            System.out.print("Ingrese el nombre del empleado:");
            empleados[f]=teclado.next();
            for(int c=0;c<sueldos[f].length;c++) {
                System.out.print("Ingrese sueldo:");
                sueldos[f][c]=teclado.nextInt();
            }
        }
El método sumar sueldos crea el vector donde se almacenará la suma de cada fila de la matriz. Mediante dos for recorremos toda la matriz y sumamos cada fila:
     sueldostot=new int[4];
        for(int f=0;f<sueldos.length;f++) {
          int suma=0;
          for(int c=0;c<sueldos[f].length;c++) {
              suma=suma+sueldos[f][c];
          }
          sueldostot[f]=suma;
        }
El método imprimirTotalPagado tiene por objetivo mostrar los dos vectores (el de nombre de los empleados y el que almacena la suma de cada fila de la matriz):
        for(int f=0;f<sueldostot.length;f++) {
            System.out.println(empleados[f]+" - "+sueldostot[f]);
        }
Por último para obtener el nombre del empleado con mayor sueldo acumulado debemos inicializar dos variables auxiliares con el primer elemento del vector de empleados y en otra auxiliar guardamos la primer componente del vector sueldostot:
        int may=sueldostot[0];
        String nom=empleados[0];
        for(int f=0;f<sueldostot.length;f++) {
            if (sueldostot[f]>may) {
                may=sueldostot[f];
                nom=empleados[f];
            }
        }
        System.out.println("El empleado con mayor sueldo es "+ nom + " que tiene un sueldo de "+may);

 

Tutorial Java 20

Matrices (cantidad de filas y columnas)

Como hemos visto para definir y crear la matriz utilizamos la siguiente sintaxis:
int[][] mat;
Creación:
mat=new int[3][4];
Como las matrices son objetos en Java disponemos por un lado del atributo length que almacena la cantidad de filas de la matriz:
System.out.println("Cantidad de filas de la matriz:" + mat.length);
También podemos preguntarle a cada fila de la matriz la cantidad de elementos que almacena:
System.out.println("Cantidad de elementos de la primer fila:" + mat[0].length);

Problema 1:

Crear una matriz de n * m filas (cargar n y m por teclado) Imprimir la matriz completa y la última fila.

Programa:

import java.util.Scanner;
public class Matriz5 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        System.out.print("Cuantas columnas tiene la matriz:");
        int columnas=teclado.nextInt();
        mat=new int[filas][columnas];
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
    
    public void imprimir() {
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }
    }
    
    public void imprimirUltimaFila() {
     System.out.println("Ultima fila");
        for(int c=0;c<mat[mat.length-1].length;c++) {
             System.out.print(mat[mat.length-1][c]+" ");
        }
    }
    
    public static void main(String[] ar) {
        Matriz5 ma=new Matriz5();
        ma.cargar();
        ma.imprimir();
        ma.imprimirUltimaFila();
    }   
}
En este ejemplo cada vez que se ejecute el programa el tamaño de la matriz lo define el usuario, para ello ingresamos por teclado dos enteros y seguidamente procedemos a crear la matriz con dichos valores:
        System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        System.out.print("Cuantas columnas tiene la matriz:");
        int columnas=teclado.nextInt();
        mat=new int[filas][columnas];
Ahora las estructuras repetitivas las acotamos preguntando a la misma matriz la cantidad de filas y la cantidad de elementos de cada fila(mat.length almacena la cantidad de filas de la matriz y mat[f].length cuando f vale cero accedemos a la cantidad de elementos de la fila cero y así sucesivamente para cada valor de f):
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
El algoritmo de impresión es idéntico al visto anteriormente con la modificación de las condiciones de los for:
    public void imprimir() {
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print(mat[f][c]+" ");
            }
            System.out.println();
        }
    }
Para imprimir la última fila debemos disponer un valor fijo en el subíndice de la fila (en este caso no podemos disponer un número fijo sino preguntarle a la misma matriz la cantidad de filas y restarle uno ya que las filas comienzan a numerarse a partir de cero: mat[mat.length-1][c])
También la condición del for debemos acceder al atributo length de la última fila mat[mat.length-1].length
        for(int c=0;c<mat[mat.length-1].length;c++) {
             System.out.print(mat[mat.length-1][c]+" ");
        }

Problema 2:

Crear una matriz de n * m filas (cargar n y m por teclado) Imprimir el mayor elemento y la fila y columna donde se almacena.

Programa:

import java.util.Scanner;
public class Matriz6 {
    private Scanner teclado;
    private int[][] mat;
    
    public void cargar() {
        teclado=new Scanner(System.in);
        System.out.print("Cuantas fila tiene la matriz:");
        int filas=teclado.nextInt();
        System.out.print("Cuantas columnas tiene la matriz:");
        int columnas=teclado.nextInt();
        mat=new int[filas][columnas];
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                System.out.print("Ingrese componente:");
                mat[f][c]=teclado.nextInt();
            }
        }
    }
        
    public void imprimirMayor() {
     int mayor=mat[0][0];
     int filamay=0;
     int columnamay=0;
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                if (mat[f][c]>mayor) {
                    mayor=mat[f][c];
                    filamay=f;
                    columnamay=c;
                }
            }
        }
        System.out.println("El elemento mayor es:"+mayor);
        System.out.println("Se encuentra en la fila:"+filamay+ " y en la columna: "+columnamay);
    }
    
    public static void main(String[] ar) {
        Matriz6 ma=new Matriz6();
        ma.cargar();
        ma.imprimirMayor();
    }   
}
Para obtener el mayor elemento de la matriz y la fila y columna donde se ubica debemos inicializar una variable mayor con el elemento de la fila cero y columna cero (esto lo hacemos suponiendo que en dicha posición se almacena el mayor):
     int mayor=mat[0][0];
     int filamay=0;
     int columnamay=0;
Luego mediante dos for recorremos todos los elementos de la matriz y cada vez que encontramos un elemento mayor al actual procedemos a actualizar la variable mayor y la posición donde se almacena:
        for(int f=0;f<mat.length;f++) {
            for(int c=0;c<mat[f].length;c++) {
                if (mat[f][c]>mayor) {
                    mayor=mat[f][c];
                    filamay=f;
                    columnamay=c;
                }
            }
        }
 
 
Fuente:  http://www.tutorialesprogramacionya.com/javaya/