From 5d2bd06d424e699852a669a9691f2a5fec9b2728 Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Tue, 5 Jul 2016 10:03:13 -0400 Subject: [PATCH] Working on arbol. Changed log system to support log file or console. --- src/cl/cromer/estructuras/Arbol.java | 95 +++++++++++++++---- .../cromer/estructuras/ArbolController.java | 45 ++++++++- src/cl/cromer/estructuras/ArbolNodo.java | 54 ++++------- src/cl/cromer/estructuras/Logs.java | 81 ++++++++++++++-- src/cl/cromer/estructuras/Main.java | 30 ++++-- src/cl/cromer/estructuras/MenuController.java | 4 +- 6 files changed, 234 insertions(+), 75 deletions(-) diff --git a/src/cl/cromer/estructuras/Arbol.java b/src/cl/cromer/estructuras/Arbol.java index 4501ae5..4a63d39 100644 --- a/src/cl/cromer/estructuras/Arbol.java +++ b/src/cl/cromer/estructuras/Arbol.java @@ -1,10 +1,15 @@ package cl.cromer.estructuras; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + public class Arbol { private ArbolNodo arbol; private int size; private int altura; private int ancho; + private List> niveles; public enum PrimerLado { IZQUERDA, @@ -15,20 +20,19 @@ public class Arbol { this.arbol = null; this.altura = 0; this.ancho = 0; + this.niveles = new ArrayList<>(); } public boolean insertar(int valor) { if (this.arbol == null) { - arbol = new ArbolNodo(valor); - arbol.setY(1); - arbol.setX(1); - ancho = 1; - altura = 1; + arbol = new ArbolNodo(valor, null); + setAncho(1); + setAltura(1); return true; } else { PrimerLado primerLado = null; - ArbolNodo nuevo = new ArbolNodo(valor); + ArbolNodo nuevo = new ArbolNodo(valor, null); ArbolNodo actual = arbol; ArbolNodo padre; while (true) { @@ -41,20 +45,23 @@ public class Arbol { // Izquerda if (primerLado == null) { primerLado = PrimerLado.IZQUERDA; - nuevo.setX(1); } - else { - nuevo.setX(nuevo.getX() + 1); - } - nuevo.setY(nuevo.getY() + 1); actual = actual.getIzquerda(); if (actual == null) { + nuevo.setPadre(padre); padre.setIzquerda(nuevo); size++; if (primerLado == PrimerLado.IZQUERDA) { - ancho++; + setAncho(getAncho() + 1); } setAltura(getAlturaRecursivo(arbol)); + + niveles = new ArrayList<>(); + for (int i = 0; i < getAltura(); i++) { + niveles.add(new ArrayList<>()); + } + getNivelesRecursivo(arbol); + return true; } } @@ -62,20 +69,23 @@ public class Arbol { // Derecha if (primerLado == null) { primerLado = PrimerLado.DERECHA; - nuevo.setX(1); } - else { - nuevo.setX(nuevo.getX() + 1); - } - nuevo.setY(nuevo.getY() + 1); actual = actual.getDerecha(); if (actual == null) { + nuevo.setPadre(padre); padre.setDerecha(nuevo); size++; if (primerLado == PrimerLado.DERECHA) { - ancho++; + setAncho(getAncho() + 1); } setAltura(getAlturaRecursivo(arbol)); + + niveles = new ArrayList<>(); + for (int i = 0; i < getAltura(); i++) { + niveles.add(new ArrayList<>()); + } + getNivelesRecursivo(arbol); + return true; } } @@ -99,12 +109,17 @@ public class Arbol { this.altura = altura; } + public List> getNiveles() { + return niveles; + } + public int getAncho() { return ancho; } public void setAncho(int ancho) { - this.ancho = ancho; + //this.ancho = ancho; + this.ancho = (int) Math.pow(2, altura - 1) - 1; } public int getAlturaRecursivo(ArbolNodo nodo) { @@ -115,14 +130,56 @@ public class Arbol { int alturaIzquerda = getAlturaRecursivo(nodo.getIzquerda()); int alturaDercha = getAlturaRecursivo(nodo.getDerecha()); if (alturaIzquerda > alturaDercha) { + nodo.setNivel(alturaIzquerda); return (alturaIzquerda + 1); } else { + nodo.setNivel(alturaDercha); return (alturaDercha + 1); } } } + public int getNivelesRecursivo(ArbolNodo nodo) { + if (nodo == null) { + return 0; + } + else { + try { + int alturaIzquerda = getNivelesRecursivo(nodo.getIzquerda()); + int alturaDerecha = getNivelesRecursivo(nodo.getDerecha()); + if (alturaIzquerda > alturaDerecha) { + if (!niveles.get(niveles.size() - alturaIzquerda - 1).contains(nodo)) { + niveles.get(niveles.size() - alturaIzquerda - 1).add(nodo); + } + if (nodo.getDerecha() == null) { + niveles.get(niveles.size() - nodo.getNivel() - 1).add(null); + } + if (nodo.getIzquerda() == null) { + niveles.get(niveles.size() - nodo.getNivel() - 1).add(null); + } + return (alturaIzquerda + 1); + } + else { + if (!niveles.get(niveles.size() - alturaDerecha - 1).contains(nodo)) { + niveles.get(niveles.size() - alturaDerecha - 1).add(nodo); + } + if (nodo.getDerecha() == null) { + niveles.get(niveles.size() - nodo.getNivel() - 1).add(null); + } + if (nodo.getIzquerda() == null) { + niveles.get(niveles.size() - nodo.getNivel() - 1).add(null); + } + return (alturaDerecha + 1); + } + } + catch (Exception exception) { + Logs.log(Level.SEVERE, exception); + return 0; + } + } + } + /** * Esta clase contiene los tipos de arboles. * diff --git a/src/cl/cromer/estructuras/ArbolController.java b/src/cl/cromer/estructuras/ArbolController.java index 9fe24e1..c003dd8 100644 --- a/src/cl/cromer/estructuras/ArbolController.java +++ b/src/cl/cromer/estructuras/ArbolController.java @@ -8,8 +8,8 @@ import javafx.scene.layout.GridPane; import javafx.scene.text.Text; import java.net.URL; +import java.util.List; import java.util.ResourceBundle; -import java.util.Stack; /** * Esta clase es para controlar todos la interfaz de Arbol. @@ -70,11 +70,23 @@ public class ArbolController implements Initializable { // TODO: Remove this arbol = new Arbol(); + /*arbol.insertar(50); + + arbol.insertar(25); + arbol.insertar(75); + + arbol.insertar(35); + arbol.insertar(15);*/ + arbol.insertar(5); arbol.insertar(4); arbol.insertar(3); arbol.insertar(2); arbol.insertar(1); + arbol.insertar(6); + arbol.insertar(7); + arbol.insertar(8); + arbol.insertar(9); } /** @@ -125,10 +137,37 @@ public class ArbolController implements Initializable { Arbol.Tipos tipos = (Arbol.Tipos) scene.getUserData(); } + private void generarGrafico() { + grafico.removerDestacar(); + Node node = contenidoArbol.getChildren().get(0); + contenidoArbol.getChildren().clear(); + contenidoArbol.getChildren().add(0, node); + + List> niveles = arbol.getNiveles(); + + Colores colores = new Colores(); + int k = niveles.get(niveles.size() - 1).size(); + for (int i = niveles.size() - 1; i >= 0 ; i--) { + int l = k - niveles.get(i).size(); + if (i != niveles.size() - 1) { + l--; + } + for (int j = 0; j < niveles.get(i).size(); j++) { + contenidoArbol.add(Grafico.crearCirculo(colores, j + "_" + i), l, i); + colores.siguinteColor(); + if (niveles.get(i).get(j) != null) { + Text text = (Text) scene.lookup("#texto_" + j + "_" + i); + text.setText(String.valueOf(niveles.get(i).get(j).getValor())); + } + l++; + } + } + } + /** * Poner los valores en el grafico. */ - private void generarGrafico() { + /*private void generarGrafico() { grafico.removerDestacar(); Node node = contenidoArbol.getChildren().get(0); contenidoArbol.getChildren().clear(); @@ -198,5 +237,5 @@ public class ArbolController implements Initializable { while(!localStack.isEmpty()) globalStack.push( localStack.pop() ); } - } + }*/ } \ No newline at end of file diff --git a/src/cl/cromer/estructuras/ArbolNodo.java b/src/cl/cromer/estructuras/ArbolNodo.java index 03cb771..43c9455 100644 --- a/src/cl/cromer/estructuras/ArbolNodo.java +++ b/src/cl/cromer/estructuras/ArbolNodo.java @@ -1,20 +1,26 @@ package cl.cromer.estructuras; final public class ArbolNodo { + private ArbolNodo padre; private ArbolNodo izquerda; private ArbolNodo derecha; private int valor; - private int y; - private int x; - private Desde desde; + private int nivel; - public ArbolNodo(int valor) { + public ArbolNodo(int valor, ArbolNodo padre) { + this.padre = padre; this.izquerda = null; this.derecha = null; this.valor = valor; - this.y = 0; - this.x = 0; - this.desde = Desde.RAIZ; + this.nivel = 1; + } + + public ArbolNodo getPadre() { + return padre; + } + + public void setPadre(ArbolNodo padre) { + this.padre = padre; } public ArbolNodo getIzquerda() { @@ -37,37 +43,11 @@ final public class ArbolNodo { return valor; } - public int getY() { - return y; + public int getNivel() { + return nivel; } - public void setY(int y) { - if (y >= 0) { - this.y = y; - } - } - - public int getX() { - return x; - } - - public void setX(int x) { - if (x >= 0) { - this.x = x; - } - } - - public Desde getDesde() { - return desde; - } - - public void setDesde(Desde desde) { - this.desde = desde; - } - - public enum Desde { - RAIZ, - IQUERDA, - DERECHA + public void setNivel(int nivel) { + this.nivel = nivel; } } diff --git a/src/cl/cromer/estructuras/Logs.java b/src/cl/cromer/estructuras/Logs.java index 3cf67ca..b8f2bf2 100644 --- a/src/cl/cromer/estructuras/Logs.java +++ b/src/cl/cromer/estructuras/Logs.java @@ -1,6 +1,8 @@ package cl.cromer.estructuras; import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; @@ -12,6 +14,24 @@ import java.util.logging.SimpleFormatter; * @author Chris Cromer */ public class Logs { + /** + * Estado de depuración. + */ + static final public boolean DEBUG = true; + + /** + * Tipos de depuración. + */ + private enum DEBUG_TIPOS { + ARCHIVO, + CONSOLA + } + + /** + * Tipo de depuración a usar. + */ + static final public DEBUG_TIPOS DEBUG_TIPO = DEBUG_TIPOS.ARCHIVO; + /** * Nombre de archivo para guardar los logs. */ @@ -22,33 +42,78 @@ public class Logs { */ static final public String LOGNAME = "EDD"; + public FileHandler fileHandler; + /** - * Crear un logger usando {@value #LOGNAME}. Guardar los logs en el archivo de {@value #LOGFILE}. Pero solo logear si Main.DEBUG es vardad. + * Crear un logger usando {@value #LOGNAME}. Guardar los logs en el archivo de {@value #LOGFILE}. Pero solo logear si {@value #DEBUG} es vardad. */ public Logs() { - if (Main.DEBUG) { + if (DEBUG && DEBUG_TIPO == DEBUG_TIPOS.ARCHIVO) { Logger logger = Logger.getLogger(LOGNAME); try { - FileHandler fileHandler = new FileHandler(LOGFILE, true); + fileHandler = new FileHandler(LOGFILE, true); logger.addHandler(fileHandler); SimpleFormatter formatter = new SimpleFormatter(); fileHandler.setFormatter(formatter); } - catch (SecurityException | IOException e) { - e.printStackTrace(); + catch (SecurityException | IOException exception) { + exception.printStackTrace(); } } } /** - * Agregar un log al logger. + * Cerrar el archivo. + */ + public void close() { + if (DEBUG && DEBUG_TIPO == DEBUG_TIPOS.ARCHIVO) { + if (fileHandler != null) { + fileHandler.close(); + } + } + } + + /** + * Agregar un log al logger con un mensaje. * * @param level Level: El tipo de error o mensaje que ha sido generado. * @param mensaje String: El mensaje de lo que pasó. */ static public void log(Level level, String mensaje) { - if (Main.DEBUG) { - Logger.getLogger(LOGNAME).log(level, mensaje); + if (DEBUG) { + if (DEBUG_TIPO == DEBUG_TIPOS.ARCHIVO) { + Logger.getLogger(LOGNAME).log(level, mensaje); + } + else { + System.out.println(mensaje); + } + } + } + + /** + * Agregar un log al logger y agregar el stack trace. + * + * @param level Level: El tipo de error o mensaje que ha sido generado. + * @param exception String: El mensaje de lo que pasó. + */ + static public void log(Level level, Exception exception) { + if (DEBUG) { + if (DEBUG_TIPO == DEBUG_TIPOS.ARCHIVO) { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + exception.printStackTrace(printWriter); + Logger.getLogger(LOGNAME).log(level, stringWriter.toString()); + printWriter.close(); + try { + stringWriter.close(); + } + catch (IOException ioexception) { + Logs.log(Level.SEVERE, ioexception); + } + } + else { + exception.printStackTrace(); + } } } } diff --git a/src/cl/cromer/estructuras/Main.java b/src/cl/cromer/estructuras/Main.java index 064893a..af2ecee 100644 --- a/src/cl/cromer/estructuras/Main.java +++ b/src/cl/cromer/estructuras/Main.java @@ -26,9 +26,9 @@ import java.util.logging.Level; */ public class Main extends Application { /** - * Estado de depuración. + * El logger. */ - static final public boolean DEBUG = true; + static private Logs logs; /** * Crear el stage y la scene para la aplicación grafica. @@ -61,14 +61,26 @@ public class Main extends Application { stage.show(); } + @Override + public void stop() { + try { + super.stop(); + } + catch (Exception exception) { + Logs.log(Level.SEVERE, exception); + } + + logs.close(); + } + /** * Inicilizar el logeo y lanzar la interfaz grafica. * * @param args String[]: Argumentos desde la consola. */ public static void main(String args[]) { - if (DEBUG) { - new Logs(); + if (Logs.DEBUG) { + logs = new Logs(); } launch(args); @@ -81,8 +93,14 @@ public class Main extends Application { * @param clase Class: La clase usado para abrir el Stream. */ static public void setIcon(Dialog dialog, Class clase) { - Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow(); - stage.getIcons().add(new Image(clase.getResourceAsStream("/cl/cromer/estructuras/images/icon.png"))); + try { + Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow(); + stage.getIcons().add(new Image(clase.getResourceAsStream("/cl/cromer/estructuras/images/icon.png"))); + } + catch (Exception exception) { + // El icono no está, no es tan critico. + Logs.log(Level.WARNING, exception); + } } /** diff --git a/src/cl/cromer/estructuras/MenuController.java b/src/cl/cromer/estructuras/MenuController.java index 2ef2722..5c23e8e 100644 --- a/src/cl/cromer/estructuras/MenuController.java +++ b/src/cl/cromer/estructuras/MenuController.java @@ -356,7 +356,7 @@ public class MenuController extends VBox implements Initializable { catch (IOException exception) { // Este error es fatal, hay que cerrar la aplicación. Logs.log(Level.SEVERE, "No se pudo abrir el archivo de fxml."); - Logs.log(Level.SEVERE, exception.getMessage()); + Logs.log(Level.SEVERE, exception); stage.close(); } @@ -373,7 +373,7 @@ public class MenuController extends VBox implements Initializable { catch (IOException exception) { // Este error es fatal, hay que cerrar la aplicación. Logs.log(Level.SEVERE, "No se pudo abrir el archivo de fxml."); - Logs.log(Level.SEVERE, exception.getMessage()); + Logs.log(Level.SEVERE, exception); stage.close(); } }