En la segunda parte de las herramientas de consola, voy a exponeros un grupo de utilidades y herramientas de uso de archivos y serialización.En el grupo de utilidades disponemos de los siguientes métodos:
waiting
.Método que realiza una espera controlada; lo utilizo cuando se visualiza un texto en la consola, se realiza una espera y se vuelve al control de programa. Este método contiene varias sobrecargas, una sin parámetros en la que se realzia una espera estándar de 3 segundos, otra con un parámetro de tiempo de espera, una más con tiempo de espera y mensaje inicial en pantalla y por último una con tres, tiempo de espera, mensaje inicial y mensaje final una vez agotado el tiempo. Creo que con estas sobrecargas están cubiertas nuestras necesidades./** * Realiza una espera controlada de 3 segundos */ public static void waiting(){ waiting(3, "", ""); } /** * Realiza una espera controlada * @param seconds Número de segundos de espera */ public static void waiting(long seconds){ waiting(seconds, "", ""); } /** * Realiza una espera controlada * @param seconds Número de segundos de espera * @param initialMessage Mensaje visualizado antes de la espera */ public static void waiting(long seconds, String initialMessage){ waiting(seconds, initialMessage, ""); } /** * Realiza una espera controlada * @param seconds Número de segundos de espera * @param initialMessage Mensaje visualizado antes de la espera * @param finalMessage Mensaje visualizado después de la espera */ public static void waiting(long seconds, String initialMessage, String finalMessage){ long initialTime=System.currentTimeMillis(); long currentTime=0; System.out.println(initialMessage); do { currentTime=System.currentTimeMillis(); } while (currentTime-initialTime<seconds*1000); System.out.println(finalMessage); }
keyDownToContinue
. Este método visualiza en pantalla ‘Pulse INTRO para continuar’ y en realidad lo que hace es capturar una entrada vacía que no usa y nos permite continuar./** * Solicita una pulsación de la tecla INTRO desde teclado para continuar * @throws IOException */ public static void keyDownToContinue() throws IOException{ Scanner in=new Scanner(System.in); System.out.println("Pulse INTRO para continuar..."); in.nextLine(); }
confirmationMessage
. Mensaje que se visualiza en pantalla solicitando continuar o no mediante la pulsación de S o N devolviendo true o false./** * Visualiza un mensaje a espera de confirmación S/N * @param message Mensaje que se visualiza * @return True para S o s. False para N o n. * @throws IOException */ public static boolean confirmationMessage(String message) throws IOException{ // Declaración de variables BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in)); String textIn=null; boolean yes=false; boolean boolIn=false; System.out.println(message); do { System.out.println("\n¿Desea continuar?\nIntroduzca S o N"); textIn = keyboardIn.readLine(); boolIn=!"S".equals(textIn) && !"s".equals(textIn) && !"N".equals(textIn) && !"n".equals(textIn); } while (boolIn); if (textIn.equals("S") || textIn.equals("s")) { yes=true; } return yes; }
clearScreen
. En las aplicaciones de consola, no podemos hacer una limpieza de la pantalla como tal, por lo que para hacer este proceso, simplemente añadimos una serie de líneas en blanco. Este método se encuentra swobrecargado dos veces con una inclusión de 20 líneas y otro donde se pueda indicar este número./** * Borra la pantalla añadiendo lineas nuevas * Valor por defecto 20 */ public static void clearScreen(){ clearScreen(20); } /** * Borra la pantalla añadiendo lineas nuevas * @param lines Número de líneas que se añadirán */ public static void clearScreen(int lines){ for (int i = 0; i < lines; i++) { System.out.println(""); } }
getRandomInteger
ygetRandomDouble
. Pocas explicaciones tienen estos métodos. Obtención de un número aleatorio entero u obtención de un número aleatorio doble./** * Devuelve un valor aleatorio entre dos números * @param m Valor inferior * @param n Valor Superior * @return Número entero aleatorio */ public static int getRandomInteger(int m, int n){ return (int)(getRandomDouble(m,n)); } /** * Devuelve un valor aleatorio entre dos números * @param m Valor inferior * @param n Valor Superior * @return Número double aleatorio */ public static double getRandomDouble(int m, int n){ double number=(Math.random()*(n-m+1)+m); return number; }
createMenu
. Este método crea un menú en base a un array de texto que será en realidad el que contiene los items del menú. Esto sería el equivalente a un ComboBox con unos items y de los cuales escogemos uno de ellos. Tiene 3 sobrecargas, la primera solo pasa como parámetro el array de texto, la segunda además incluye un texto que se usará como cabecera de menú y por último uno más que añade el caracter utilizado como marco del menú, el cual en su defecto se usa un asterisco ‘*’. Mostramos el código y una muestra de como quedaría./** * Crea un menú desde un array de cadenas con asterisco por defecto * @param arg Array String. Items del menú * @return Cadena de texto con menú de consola */ public static String createMenu(String arg[]){ return createMenu(arg,"*",""); } /** * Crea un menú desde un array de cadenas * @param arg Array String. Items del menú * @param header Cabecera usada antes del menu * @return Cadena de texto con menú de consola */ public static String createMenu(String arg[], String header){ return createMenu(arg,"*",header); } /** * Crea un menú desde un array de cadenas * @param arg Array String. Items del menú * @param stringMenu Caracter utilizado para el marco del menú * @param header Cabecera usada antes del menu * @return Cadena de texto con menú de consola */ public static String createMenu(String arg [], String stringMarcoMenu, String header){ // Advertencias y validación if (stringMarcoMenu.length()>1){ return "La cadena de menú debe contener solo un carácter."; } if (arg.length>99) { return "La longitud máxima del menú, debe ser inferior a 100"; } // Declaración de variables int maxLong=0; String asterisk=""; String textOut=""; // Determinar la longitud máxima del texto for (int i = 0; i maxLong?arg[i].length():maxLong; } String [] temp=header.split("\\n"); for (int i = 0; i maxLong?temp[i].length():maxLong; } // Cadena marco del menú // Sumo 10 para compensar los espacios, stringMenu, paréntesis y el número // crear el menú for (int i = 0; i < maxLong + 10; i++) { asterisk += stringMarcoMenu; } textOut +=asterisk + "\n"; // cabecera si la hay textOut += header + dumpChar(" ", maxLong-header.length()) + "\n" + asterisk + "\n"; for (int i = 0; i < arg.length; i++) { textOut += stringMarcoMenu + " (" + (i+1) + ") " + arg[i]; for (int j = arg[i].length(); j <maxLong+3 ; j++) { textOut += " "; } textOut += stringMarcoMenu+ "\n"; } textOut +=asterisk + "\n"; return textOut; }
una muestra de como quedaría el menú del sistema planetario pasándole como parámetro el array
String[] menu={"Calcular distancia entre dos objetos", "Calcular atracción gravitacional", "Calcular tiempo (línea recta)", "Listar objetos", "Salir"};
y como texto de cabecera ‘Sistema Solar’.********************************************** Sistema Solar ********************************************** * (1) Calcular distancia entre dos objetos * * (2) Calcular atracción gravitacional * * (3) Calcular tiempo (línea recta) * * (4) Listar objetos * * (5) Salir * ********************************************** Introduzca la opción...
Grupo de herramientas de archivos:
createFile
.Pasando la ruta de un archivo, crea este.createFolder
.Pasando la ruta de la carpeta, crea esta.existFile
. Comprueba si un archivo existe en la ruta especificada
/** * Crea un nuevo archivo * @param path Ruta del archivo * @throws IOException */ public static void createFile(String path) throws IOException{ try { File myFile=new File(path); if (myFile.createNewFile()) System.out.println("El fichero se ha creado correctamente"); else System.out.println("No ha podido ser creado el fichero"); } catch (IOException ioe) { ioe.printStackTrace(); } } /** * Crea una nueva carpeta * @param path Ruta de la carpeta * @throws IOException */ public static void createFolder(String path) throws IOException{ try { File myFile=new File(path); if (myFile.mkdir()) System.out.println("La carpeta se ha creado correctamente"); else System.out.println("No ha podido ser creada la carpeta"); } catch (Exception ex){ System.out.println(ex.getMessage()); } } /** * Comprueba si existe un archivo * @param path Ruta del archivo * @return True si existe. False si no existe */ public static boolean existFile(String path){ File myFile=new File(path); return myFile.exists(); }
Serialización. Por si alguien no sabe lo que es serialización, es guardar en un archivo, en memoria o en una base de datos, un objeto en bytes y deserializar es el proceso inverso, obtener un objeto desde un archivo, memoria o base de datos, de modo que podemos guardar objetos para luego extraerlos y usarlos de nuevo. Por tanto, los métodos de este grupo son serializar
y deserializar
:
/** * Serializa un objeto en un archivo * @param iObject Objeto que se serializará * @param filePath Ruta del archivo */ public static void serializar(Object iObject, String filePath){ FileOutputStream fileOutputStream = null; ObjectOutputStream salidaSerializada = null; try { fileOutputStream = new FileOutputStream(filePath); salidaSerializada = new ObjectOutputStream(fileOutputStream); salidaSerializada.writeObject(iObject); salidaSerializada.close(); fileOutputStream.close(); } catch (FileNotFoundException e) { System.out.println(e.getMessage()); } catch (IOException e) { System.out.println(e.getMessage()); } finally { try { if(fileOutputStream!=null) fileOutputStream.close(); if(salidaSerializada!=null) salidaSerializada.close(); } catch (IOException e) { System.out.println(e.getMessage()); } } } /** * Retorna un objeto deserializado desde un archivo * @param filePath Ruta del archivo * @return Objeto deserializado * @throws IOException * @throws ClassNotFoundException */ public static Object deserializar(String filePath) throws IOException, ClassNotFoundException{ FileInputStream fileInputStream = null; ObjectInputStream entradaSerializada = null; Object iObject=null; try { fileInputStream=new FileInputStream(filePath); entradaSerializada=new ObjectInputStream(fileInputStream); iObject=entradaSerializada.readObject(); entradaSerializada.close(); fileInputStream.close(); return iObject; } catch (FileNotFoundException e) { System.out.println(e.getMessage()); } catch (IOException e) { System.out.println(e.getMessage()); } finally { try { if(fileInputStream!=null) fileInputStream.close(); if(entradaSerializada!=null) entradaSerializada.close(); } catch (IOException e) { System.out.println(e.getMessage()); } return iObject; } }
Pues ya que tenemos nuestras herramientas,os muestro el método utilizado para crear el menú en el sistema planetario el cual crea el menú, entra en un bucle do while
y dentro de este se encuentra una instrucción switch
con las opciones que podría seleccionar el usario y dentro de cada caso, las acciones a realizar, las cuales utilizan muchos de los métodos incluidos en esta clase.
Saludos «der Waki»
private static void menuPrincipal() throws IOException, ParseException{ // DECLARACIÓN DE VARIABLES String opcionMenu = ""; String[] menu={"Calcular distancia entre dos objetos", "Calcular atracción gravitacional", "Calcular tiempo (línea recta)", "Listar objetos", "Salir"}; // MENU, INICIO Y FIN do { System.out.println(ConsoleUtilities.createMenu(menu,sl.nombre)); opcionMenu = String.valueOf(ConsoleUtilities.readText("Introduzca la opción...")); switch (opcionMenu) { case "1": // Calcular distancia entre objetos String str1 = ConsoleUtilities.readText("Introduzca el nombre del primer objeto..."); String str2=""; ObjetoSistema obj1=sl.getObjeto(str1); ObjetoSistema obj2=null; if (obj1==null) { System.out.println("El objeto no existe."); } else { str2 = ConsoleUtilities.readText("Introduzca el nombre del segundo objeto..."); obj2=sl.getObjeto(str2); if (obj2==null) { System.out.println("El objeto no existe."); } else { System.out.println(ConsoleUtilities.toNumber(obj1.calcularDistancia(obj2)/1000) + " Km"); } } ConsoleUtilities.keyDownToContinue(); break; case "2": // Calcular atracción gravitacional entre dos objetos String str3 = ConsoleUtilities.readText("Introduzca el nombre del primer objeto..."); String str4=""; ObjetoSistema obj3=sl.getObjeto(str3); ObjetoSistema obj4=null; if (obj3==null) { System.out.println("El objeto no existe."); } else { str4 = ConsoleUtilities.readText("Introduzca el nombre del segundo objeto..."); obj4=sl.getObjeto(str4); if (obj4==null) { System.out.println("El objeto no existe."); } else { double calculo=obj3.getAtraccion(obj4); System.out.println(ConsoleUtilities.toNumber(calculo) + " Newton"); } } ConsoleUtilities.keyDownToContinue(); break; case "3": // Calcular velocidad String str5 = ConsoleUtilities.readText("Introduzca el nombre del primer objeto..."); String str6=""; ObjetoSistema obj5=sl.getObjeto(str5); ObjetoSistema obj6=null; if (obj5==null) { System.out.println("El objeto no existe."); } else { str6 = ConsoleUtilities.readText("Introduzca el nombre del segundo objeto..."); obj6=sl.getObjeto(str6); if (obj6==null) { System.out.println("El objeto no existe."); } else { double calculoKm=obj5.calcularDistancia(obj6)/1000; double velocidad = ConsoleUtilities.readDouble("Introduzca la velocidad km/h (Si pulsa INTRO, se asignará 28000 km/h... ",28000); if (velocidad>0){ double tiempo=(calculoKm / velocidad)/(24); System.out.printf("Invertirá para recorrer %s Km a una velocidad de %s Km/h, %s días\n", ConsoleUtilities.toNumber(calculoKm),ConsoleUtilities.toNumber(velocidad), ConsoleUtilities.convertToTime(tiempo*60*60*24)); } else { System.out.println("Velocidad no válida"); } } } ConsoleUtilities.keyDownToContinue(); break; case "4": // Listar objetos menuListado(); break; } } while (!opcionMenu.equals("5")); ConsoleUtilities.clearScreen(); System.out.println("La aplicación ha finalizado"); }