Como ya os comenté en un post anterior, es importante que vayamos creando nuestras clases de código reutilizable, como por ejemplo en este caso os voy a mostrar una clase de herramientas y utilidades que uso para aplicaciones de consola en Java. Como las aplicaciones de consola suelen ser eso, texto puro en consola, a veces es necesario obtener claridad en los textos o en otro caso simplificar acciones que comunmente realizamos, para ello, inlcuyo dentro de la clase una serie de métodos estáticos que me van a permitir crear más fácil y rápido mis aplicaciones.

Dentro de la clase he creado distintos grupos de código, lo primero para aclararme y no repetir métodos o saber que es lo que tengo y en segundo lugar cuando el número de métodos es grande, es conveniente haber ordenado y agrupado nuestro código. A continuación expongo los grupos y método a método.

  • Solicitudes desde teclado. En una aplicación de consola es normal solicitar datos desde teclado ya que no tenemos controles TextBox, ComboBox ni nada por el estilo, por tanto tenemos que ingeniarnos un método fácil y práctico para solicitar información desde el teclado y pasarla a la aplicación. En este caso, he creado varios métodos estáticos y sus sobrecargas para obtener texto, obtener números, textos o fechas.
    • Lectura de texto. En este caso, existen dos métodos de lectura de texto, uno sobrecargado para leer texto y otro para leer varias veces el texto y devolver un array.readText es un método al cual se le pasan dos parámetros, el primero es el texto que se muestra por pantalla al solicitar el texto y el segundo parámetro, un valor booleano que permite si el valor que se captura desde el teclado puede ser un elemento vacío. El método crea un objeto BufferedReader, muestra por pantalla el textoy entra en un bucle do... while hasta obtener el texto. Una vez capturado desde el teclado lo devuelve. readText tiene otro método sobrecargado con un solo parámetro enviando el parámetro allowEmpty con un false. Por último el método readArrayText solicita mediante el método readText tantas cadenas de texto como necesite el usuario devolviendo una array de cadena.( Lo he limitado a 8 cadenas como podía haberlo hecho a 100). Un ejemplo. String stringFromKeyboard = ConsoleUtilities.readText("Introduzca el nombre del usuario...");, solicitando por pantalla el texto del primer parámetro y asignando e la variable stringFromKeyboard el valor obtenido desde el teclado.
          /**
          * Devuelve un valor desde el teclado
          * @param textIn Texto que se visualiza en la consola
          * @return Texto procedente del teclado
          * @throws IOException
          */
          public static String readText(String textIn, boolean allowEmpty) throws IOException{
      
              // Declaración de variables
              BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in));
              String textOut=null;
      
              // Imprimir texto de consola
              System.out.println(textIn);
      
              // Solicitar datos desde teclado
      
              do {
                  textOut=keyboardIn.readLine();
              } while (ConsoleTools.isNullOrEmpty(textOut) && !allowEmpty);
      
              // Retornar texto
              return textOut;
          }
      
          /**
          * Devuelve un valor desde el teclado
          * @param textIn Texto que se visualiza en la consola
          * @return Texto procedente del teclado
          * @throws IOException
          */
          public static String readText(String textIn) throws IOException{
              return ConsoleTools.readText(textIn, false);
          }
      
          /**
          * Devuelve un array de textos. Limitado a 8 textos
          * @param textIn Texto que se visualiza en la consola
          * @return Array de texto
          */
          public static String[] readArrayText(String textIn) throws IOException{
              int n=0;
              int indexMax=8;
      
              String[] texts=new  String[indexMax];
      
              do {
                  texts[n]=ConsoleTools.readText(textIn);
                  n++;
              } while (ConsoleTools.confirmationMessage("¿Desea introducir más textos?") || n==indexMax);
      
              return texts;
      
          }
      
    • Lectura de números. Para obtener números desde teclado y asegurarnos que estos son lo que son y del tipo que son, uso un método sobrecargado para leer números enteros, otro para enteros positivos y por último otro sobrecargado para leer números con precisión doble. En todos ellos, se validan los datos comprobando que son del tipo que se solicita y que realmente son números y no otro objeto.
      Existe un método sobrecargado para lectura de números enteros, uno que tiene dos parámetros readInteger(String textIn, int defaultValue)pasando una cadena que se visualizará por pantalla y otro que pasará un valor por defecto en caso de no introducir ningún dato y otro método readInteger(String textIn)que solo pasa la cadena. Otro método para enteros es readPositiveInteger(String textIn) el cual además ed validar que es numérico y entero, comprueba que es positivo.
      Para lectura de números con precisión doble, disponemos de dos métodos sobrecargados igualmente que para números enteros.

          /**
          * Devuelve un valor entero desde el teclado
          * @param textIn Texto que se visualiza en la consola
          * @return Número procedente desde el teclado
          */
          public static int readInteger(String textIn) throws IOException{
              // Declaración de variables
              BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in));
              int numberOut=0;
              String numberOutToString=null;
              boolean validate=false;
      
              // Imprimir texto de consola
              System.out.println(textIn );
      
              // Solicitar datos desde teclado
              do {
                  numberOutToString=keyboardIn.readLine();
                  validate=ConsoleTools.isInteger(numberOutToString);
                  // Mensaje de Validación errónea
                  if (!validate) {
                      System.out.println("No es un valor válido. Introduzca un número entero.");
                  }
              } while (!validate);
      
              numberOut=Integer.parseInt(numberOutToString);
              // Retornar número
              return numberOut;
          }
      
          public static int readInteger(String textIn, int defaultValue) throws IOException{
              // Declaración de variables
              BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in));
              int numberOut=0;
              String numberOutToString=null;
              boolean validate=false;
      
              // Imprimir texto de consola
              System.out.println(textIn );
      
              // Solicitar datos desde teclado
              do {
                  numberOutToString=keyboardIn.readLine();
                  validate=ConsoleTools.isInteger(numberOutToString);
      
                  if (!validate) {
                      numberOutToString=String.valueOf(defaultValue);
                      validate=true;
                  }
              } while (!validate);
      
              numberOut=Integer.parseInt(numberOutToString);
              // Retornar número
              return numberOut;
          }
      
          /**
          * Devuelve un valor entero y positivo desde el teclado
          * @param textIn Texto que se visualiza en la consola
          * @return Número procedente desde el teclado
          */
          public static int readPositiveInteger(String textIn) throws IOException{
              // Declaración de variables
              BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in));
              int numberOut=0;
              String numberOutToString=null;
              boolean validate=false;
      
              // Imprimir texto de consola
              System.out.println(textIn );
      
              // Solicitar datos desde teclado
              do {
                  numberOutToString=keyboardIn.readLine();
                  validate=ConsoleTools.isPositiveInteger(numberOutToString);
                  // Mensaje de Validación errónea
                  if (!validate) {
                      System.out.println("No es un valor válido. Introduzca un número entero.");
                  }
              } while (!validate);
      
              numberOut=Integer.parseInt(numberOutToString);
              // Retornar número
              return numberOut;
          }
      
          /**
           * Devuelve un valor entero desde el teclado
           * @param textIn Texto que se visualiza en la consola
           * @return Número procedente desde el teclado
           * @throws java.io.IOException
           */
          public static double readDouble(String textIn) throws IOException{
              // Declaración de variables
              BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in));
              double numberOut=0;
              String numberOutToString=null;
              boolean validate=false;
      
              // Imprimir texto de consola
              System.out.println(textIn );
      
              // Solicitar datos desde teclado
              do {
                  numberOutToString=keyboardIn.readLine();
                  validate=ConsoleTools.isNumeric(numberOutToString);
                  // Mensaje de Validación errónea
                  if (!validate) {
                      System.out.println("No es un valor válido. Introduzca un número con doble precisión.");
                  }
              } while (!validate);
      
              numberOut=Double.parseDouble(numberOutToString);
              // Retornar número
              return numberOut;
          }
      
          /**
           * Devuelve un valor entero desde el teclado
           * @param textIn Texto que se visualiza en la consola
           * @param defaultValue Valor por defecto que se asigna en caso de no validez de entrada
           * @return Número procedente desde el teclado o valor por defecto
           * @throws IOException
           */
          public static double readDouble(String textIn, double defaultValue) throws IOException{
              // Declaración de variables
              BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in));
              double numberOut=0;
              String numberOutToString=null;
              boolean validate=false;
      
              // Imprimir texto de consola
              System.out.println(textIn );
              // Solicitar datos desde teclado
              do {
                  numberOutToString=keyboardIn.readLine();
                  validate=ConsoleTools.isNumeric(numberOutToString);
                  // Mensaje de Validación errónea
                  if (!validate) {
                      numberOutToString=String.valueOf(defaultValue);
                      validate=true;
                  }
              } while (!validate);
      
              numberOut=Double.parseDouble(numberOutToString);
      
              // Retornar número
              return numberOut;
          }
      
    • Lectura de fechas. Para leer fechas, uso un solo método readDate(String textIn) que comprueba que es una fecha y que contiene el formato correcto (dd/MM/yyyy).
      public static Date readDate(String textIn) throws IOException, ParseException{
              // Declaración de variables
              BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in));
              SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
              boolean exit=false;
              Date dateTemp=new Date();
              String date;
              // Imprimir texto de consola
              System.out.println(textIn);
      
              // Solicitar datos desde teclado
      
              do {
                  date = keyboardIn.readLine();
                  try{
                      dateTemp = df.parse(date);
      
                  } catch (Exception ex){
                  }
      
                  if (!df.format(dateTemp).equals(date)){
                      if (ConsoleTools.confirmationMessage("El formato es inválido, ¿desea introducir una nueva fecha?. " +
                              "En caso contrario, se insertará la fecha actual")) {
                      }
                      else{
                          dateTemp=new Date();
                          exit=true;
                      }
                  } else {
                      exit=true;
                  }
      
              } while (!exit);
      
              // Retornar fecha
              return dateTemp;
          }
      
  • Validación. En este grupo se incluyen métodos de validación que devuelven un valor booleano con true si se cumple la validación o false en caso contrario, como por ejemplo si el valor de una cadena es vacía o nulaboolean isNullOrEmpty(String textIn), si un número es positivo entero boolean isPositiveInteger(String numberIn), si es número entero boolean isInteger(String numberIn), si es un valor númerico doble boolean isInteger(String numberIn) o comprobando si es una fecha es válida boolean isDate(String date).
        /**
         * Comprueba si un texto es vacio o nulo
         * @param textIn Texto de entrada
         * @return True. Si es vació o nulo. False. Si contiene texto
         */
        public static boolean isNullOrEmpty(String textIn){
    
            return textIn=="" || textIn.isEmpty() || textIn==null?true:false;
    
        }
    
        /**
         * Comprueba si un número es entero y positivo
         * @param numberIn. Número de entrada
         * @return
         * True. Si es positivo y entero.
         * False. No es positivo o no es un número entero
         */
        public static boolean isPositiveInteger(String numberIn){
    
            int numberOut=0;
            // Primera validación convirtiendo el número a entero
            try {
                numberOut=Integer.parseInt(numberIn);
            } catch (Exception ex) {
                return false;
            }
            // Segunda validación comprobando que es positivo
            return numberOut>0;
        }
    
        /**
         * Comprueba si un número es entero
         * @param numberIn. Número de entrada
         * @return
         * True. Si es positivo y entero.
         * False. No es positivo o no es un número entero
         */
        public static boolean isInteger(String numberIn){
    
            int numberOut=0;
            // Primera validación convirtiendo el número a entero
            try {
                numberOut=Integer.parseInt(numberIn);
            } catch (Exception ex) {
                return false;
            }
    
            return true;
        }
    
        /**
         * Comprueba si la cadena es un número
         * @param numberIn. Número de entrada
         * @return
         * True. Si es un número.
         * False. No es un número
         */
        public static boolean isNumeric(String numberIn){
    
            double numberOut=0;
            // Primera validación convirtiendo el número a double
            try {
                numberOut=Double.parseDouble(numberIn);
            } catch (Exception ex) {
                return false;
            }
    
            return true;
        }
    
        /**
         * Comprueba si la cadena es una fecha válida
         * @param date Fecha de compración
         * @return
         * True. Si es una fecha.
         * False. No es una fecha
         */
        public static boolean isDate(String date){
            try{
                SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
                Date dateTemp=new Date();
                dateTemp = df.parse(date);
                return true;
                } catch (Exception ex){
                    return false;
                }
        }
    
  • Formatos y conversiones. En este grupo, se incluyen métodos que permiten mostrar los resultados de nuestras aplicaciones de un modo más legible por los que podemos disponer de un método que convierte un texto o número a un texto con formato de la moneda local String toCurrency(String number), un método que convierte a número con formato pudiendo especificar un número de dígitos String toNumber(double number) o String toNumber(double number, int digits), métodos para rellenar por la izquierda o por la derecha de un caracter String padRight(String text, int number) y String padLeft(String text, int number), un método que retorna una cadena un número de veces String dumpChar(String string, int lenght), un método que añade un borde sobre un texto String addBorder( String text, int longLine), método que convierte una fecha en formato corto String toShortDate(Date date), o convertir un tiempo en segundos en una cadena expresada en segundos, minutos, horas, días, meses y años String convertToTime(double tiempoSegundos).
    /**
         * Convierte un número a texto con formato de moneda.
         * Separador de miles, dos decimales y moneda
         * @param number Número a convertir
         * @return Cadena con formato de moneda
         */
        public static String toCurrency(String number){
            return ConsoleTools.toCurrency(Integer.parseInt(number));
        }
    
        /**
         * Convierte un número a texto con formato de moneda.
         * Separador de miles, dos decimales y moneda
         * @param number Número a convertir
         * @return Cadena con formato de moneda
         */
        public static String toCurrency(int number){
            NumberFormat fn=NumberFormat.getCurrencyInstance();
            return fn.format(number);
        }
    
        /**
         * Convierte un número a texto con formato de moneda.
         * Separador de miles, dos decimales y moneda
         * @param number Número a convertir
         * @return Cadena con formato de moneda
         */
        public static String toCurrency(double number){
            NumberFormat fn=NumberFormat.getCurrencyInstance();
            return fn.format(number);
        }
    
        /**
         * Convierte un número a texto con formato
         * @param number Número a convertir
         * @return Cadena con formato
         */
        public static String toNumber(double number){
            NumberFormat fn=NumberFormat.getNumberInstance();
            return fn.format(number);
        }
    
        /**
         * Convierte un número a texto con formato de número de decimales específico
         * @param number Número a convertir
         * @param digits Número de decimales
         * @return Cadena con formato
         */
        public static String toNumber(double number, int digits){
            NumberFormat fn=NumberFormat.getNumberInstance();
            fn.setMaximumFractionDigits(digits);
            return fn.format(number);
        }
        /**
         * Rellena por la derecha n espacios y
         * recorta el texto cuando es mayor añadiéndole
         * puntos suspensivos
         * @param text Texto formateado
         * @param number Número de espacios
         * @return Cadena de texto formateada
         */
        public static String padRight(String text, int number){
            if (text.length()>number) {
                text=text.substring(0, number-3) + "...";
            }
            return String.format("%1$-" + number + "s", text);
        }
    
        /**
         * Rellena por la izquierda n espacios y
         * recorta el texto cuando es mayor añadiéndole
         * puntos suspensivos
         * @param text Texto formateado
         * @param number Número de espacios
         * @return Cadena de texto formateada
         */
        public static String padLeft(String text, int number){
            if (text.length()>number) {
                text=text.substring(0, number-3) + "...";
            }
            return String.format("%1$" + number + "s", text);
        }
    
        /**
         * Retorna un caracter repetido un número de veces
         * @param string Cadena de texto
         * @param lenght Número de veces que se repite
         * @return Cadena de texto
         */
        public static String dumpChar(String string, int lenght){
            String textOut="";
    
            for (int i = 0; i < lenght; i++) {
                textOut +=string;
            }
            return textOut;
        }
    
         /**
         * Devuelve un borde de texto superior e inferior
         * @param text Texto al que se le añade el borde
         * @param longLine Longitud del borde
         * @return Cadena de texto formateada con borde
         */
        public static String addBorder( String text, int longLine){
            String border = "";
            border += "+";
            for (int i = 0; i < longLine; i++) {
                border += "-";
            }
            border += "+\n";
    
             return border + text + border;
        }
    
        /**
         * Convierte una fecha en formato corto
         * @param date Fecha a convertir
         * @return Cadena de texto con la fecha
         */
        public static String toShortDate(Date date){
            SimpleDateFormat df=new SimpleDateFormat("dd/MM/yyyy");
    
            return df.format(date);
        }
    
         /**
         * Convierte un tiempo en segundos en sg, min, horas, días, meses y años
         * @param tiempoSegundos Tiempo en segundos
         * @return Texto
         */
        public static String convertToTime(double tiempoSegundos){
    
            double segundos =  Math.floor(tiempoSegundos % 60);
            double aux1 =((tiempoSegundos-segundos) / 60);
            double minutos = Math.floor(aux1 % 60);
            aux1 = (aux1-minutos) / (60);
            double horas = Math.floor(aux1 % 24);
            aux1 = (aux1-horas) / 24;
            double dias = Math.floor(aux1 % 30);
            aux1 = (aux1-dias) / 30;
            double meses = Math.floor(aux1 % 12);
            aux1 = (aux1 - meses)/12;
            double años = Math.floor(aux1);
    
            String sAños = años > 0? (años==1?"1 año":(int)años + " años "):"";
            String sMes = meses > 0? (meses==1?"1 mes":(int)meses + " meses "):"";
            String sDias = dias > 0? (dias==1?"1 día":(int)dias + " días "):"";
            String sHoras = horas > 0? (horas==1?"1 hora":(int)horas + " horas "):"";
            String sMinutos = minutos > 0? (minutos==1?"1 minuto":(int)minutos + " minutos "):"";
            String sSegundos = segundos > 0? (segundos==1?"1 segundo":(int)segundos + " segundos "):"";
    
            return sAños + sMes + sDias + sHoras + sMinutos + sSegundos;
        }
    

Como podéis apreciar, pequeños métodos que nos permiten crear aplicaciones mucho más rápido.
En la próxima entrega, algunas utilidades de consola más como un método que crea menús automáticamente.

Un saludo

Anuncio publicitario

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s