Download Untitled
Document related concepts
no text concepts found
Transcript
J. ERNESTO ANTONIO PICHARDO MATRICULA: 99216021 OSCAR ALEJANDRO MORALES GUTIÉRREZ MATRICULA: 96322402 LICENCIATURA: INGENIERÍA ELECTRÓNICA ÁREA DE CONCENTRACIÓN: COMUNICACIONES PROYECTO TERMINAL DESARROLLO DE UN INTERFAZ GRAFICO PARA UN SIMULADOR DE EVENTOS DISCRETOS Octubre de 2004. Índice general 1. AGRADECIMIENTOS 3 2. INTRODUCCIÓN 2.1. Interfaces de Usuario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2. La arquitectura del Simulador . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3. Desarrollo y Creación de una GUI . . . . . . . . . . . . . . . . . . . . . . . . . . 4 5 6 7 3. MANUAL DE USUARIO 3.1. Partes de la GUI . . . . 3.1.1. Menú Archivo . . 3.2. Menú Edición . . . . . . 3.2.1. Menú Simulación 3.3. Menú Ayuda . . . . . . 3.4. Barra de Herramientas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4. MANUAL TÉCNICO 4.1. Paquete archivos . . . . . . . . . . . . . . . . . 4.1.1. Clase cArchivo . . . . . . . . . . . . . . 4.2. Paquete elementos . . . . . . . . . . . . . . . . 4.2.1. Clase cCanal . . . . . . . . . . . . . . . 4.2.2. Clase cNodo . . . . . . . . . . . . . . . . 4.2.3. Clase cPaquete . . . . . . . . . . . . . . 4.2.4. Clase cPaqueteAux . . . . . . . . . . . . 4.2.5. Clase cPaqueteCoordenadas . . . . . . . 4.3. Paquete Interfaces . . . . . . . . . . . . . . . . 4.3.1. Clase AccionBotonSimular . . . . . . . . 4.3.2. Clase cIContenedor de Nodos . . . . . . 4.3.3. Clase SimuladorFrame AboutBox . . . . 4.3.4. Clase cNCanal . . . . . . . . . . . . . . 4.3.5. Clase cNNodos . . . . . . . . . . . . . . 4.3.6. Clase cNPaquete . . . . . . . . . . . . . 4.3.7. Clase cNPaqueteCoordenadas . . . . . . 4.3.8. Clase DebugHelper . . . . . . . . . . . . 4.3.9. Clase EventosMouseContenedorDeNodos 4.3.10. Clase Filtro . . . . . . . . . . . . . . . . 4.3.11. Clase ManejoDeArchivosEntrada . . . . 4.3.12. Clase ManejoDeArchivosSalida . . . . . 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 11 12 14 16 17 18 . . . . . . . . . . . . . . . . . . . . . 19 19 19 20 20 21 22 24 25 26 26 27 29 31 31 33 37 37 39 42 42 45 Capı́tulo 1 AGRADECIMIENTOS Oscar. Quisiera agradecer principalmente a mi Mamá y a Marissa por todo el apoyo que me brindaron durante toda la carrera, creo que sin su apoyo no lo hubiera logrado. Sin ningun orden particular agradezco a mis hermanos Carlos y Mario, Erick (spaguetti broken heart), a Milton de puerto rico, a Jorge ”and justice” Axel ”amine”, a Xelajú ”xelos”, Memo, Francisco ”rafita”, la pandilla del kiosco, Cesar ”muerte”, Ceja, Alvaro Salazar +, su contribución fué el estar ahı́ cuando necesitaba que alguien estuviera conmigo :-) ; gracias al football americano por no dejarme caer cuando estaba en la orilla del pozo y por enseñarme a luchar siempre; gracias a mis mascotas tencha, inquilina, solovino, negra, cuerpito,orejas, y a todas las que me han acompañado en mi vida (me van a ayudar a cruzar el rı́o), y por ultimo quisiera dedicar este documento a alguien que todavı̀a no está aquı́ fı́sicamente pero si en espı́ritu (te estoy esperando # 10). Ernesto. Si a alguien tengo que darle las gracias sin lugara a dudas es a mi Mamá que toda mi vida, y en especial durante el tiempo que estuve en la universidad me motivo para continuar y nunca darme por vencido aun cuando parecı́a que el esfuerzo no tenia sentido. A Yedzy que siempre tiene una palabra de aliento y motivación para no claudicar y durante todo este tiempo fue mi razón. Mis hermanos Jose Luis y Alfredo que a su modo siempre me dieron motivos para poner el nombre de la familia en alto, Memo el vaio y todos mis amigos que de alguna forma contribuyeron en mi paso por la universidad. 3 Capı́tulo 2 INTRODUCCIÓN La necesidad de eficientar el uso de los recursos dentro de las redes de telecomunicaciones ha generado el estudio y desarrollo de algoritmos de enrutamiento para el transporte de paquetes de información. Estos algoritmos requieren de un modelo que simule su comportamiento a nivel fı́sico con el cuál el investigador pudiera corroborar sus teorı́as sin necesidad de avocarse a una implementación fı́sica. La programación orientada a objetos (POO) permite modelar los objetos del mundo real mediante sus contrapartes en software, nos proporciona una forma mas natural e intuitiva de observar el proceso de programación, es decir, modelar el mundo real en lo que respecta a sus atributos y comportamientos. Una caracterı́stica esencial de la POO es la reutilización del software; podemos crear clases propias a partir de clases ya creadas con anterioridad y de esta forma recurrimos a las relaciones de herencia para personalizarlas. Ayudándonos de esta técnica de programación nos fué posible la elaboración de esta primera versión del simulador de eventos discretos cuyas caracterı́sticas iremos presentando a lo largo de este documento. Existen actualmente varios lenguajes de programación con caracterı́sticas de POO, pero que sus aplicaciones están ı́ntimamente ligadas a la plataforma en la cual se ejecuten; por otro lado el lenguaje Java es una herramienta de programación que permite crear poderosas aplicaciones independientes de la arquitectura de la máquina y del sistema operativo bajo el que se esté trabajando. Java fué desarrollado por la compañı́a Sun Mycrosystems y se introdujo como lenguaje de programación para computadoras a finales de 1995. Al programar en Java no se parte desde cero, cualquier aplicación que se desarrolle se apoya en un gran número de clases preexistentes. El principal objetivo del lenguaje Java es llegar a ser el nexo universal que conecte a los usuarios con la información, esté ésta situada en el equipo terminal local, en un servidor de Web, en una base de datos o en cualquier otro lugar. Al compilar un programa escrito en lenguaje Java se genera un archivo de bytecodes el cual es traducido a lenguaje máquina por la Máquina Virtual de Java (JVM por sus siglas en inglés), de tal forma que para que una aplicación creada en lenguaje Java se ejecute en nuestra máquina, solamente es necesario que instalemos la JVM. El código desarrollado en Java es neutro, y es la JVM quien interpreta este código neutro convirtiéndolo a código particular de la CPU o chip utilizada.Por ejemplo, una aplicación creada en Visual Basic podrá ser ejecutada exitosamente en un entorno Windows, pero no en un entorno Unix o Solaris, en cambio una aplicación desarrollada en Java solo requiere que en la computadora esté instalada la JVM. La compañı́a Sun describe el lenguaje Java como simple, orientado a objetos, distribuido, interpretado, robusto, seguro, de arquitectura neutra, portable, de altas prestaciones, multitarea y dinámico. No es propósito de este documento el detallar las caracterı́sticas de la POO ni de el lenguaje Java, ası́ que si al lector le interesa ahondar mas en estos temas puede recurrir a las referencias bibliográficas al final de este trabajo. 4 CAPÍTULO 2. INTRODUCCIÓN 2.1. 5 Interfaces de Usuario Para poder interactuar con una computadora es necesario contar con un conjunto de herramientas que faciliten la comunicaciónentre la máquina y el usuario. A nivel hardware los elementos básicos para efectuar esta comunicación son el teclado, el mouse y el monitor. Cualquier mensaje que el usuario pretenda mandar hacia la computadora será generalmente transmitido utilizando el mouse o el teclado y a su vez el usuario obtendrá una respuesta de dicho mensaje através del monitor (que es la salida standard). La evolución de las interfaces de usuario va de la mano con la de los sistemas operativos, inclusive, actualmente la interfaz constituye un elemento fundamental en cualquier sistema operativo. Las primeras interfaces de usuario que comenzaron a utilizarse fueron las llamadas CUIs (C ommand-line U sers I nterfaces). Estas interfaces son caracterı́sticas de MS-DOS o Linux en sus primeras versiones, el usuario escribe órdenes utilizando un lenguaje formal con un vocabulario y una sintaxis propia através del teclado y las órdenes están encaminadas a realizar una tarea determinada. Este tipo de interfaces son potentes, flexibles y absolutamente todo está controlado por el usuario aunque algunos de sus inconvenientes son la memorización de comandos cuya sintaxis es a veces mal comprendida y la poca información que suele proporcionar a un usuario novel. Este tipo de interfaces están dirigidas a usuarios expertos acostumbrados a la comunicación con una computadora utilizando simplemente una consola de lı́nea de comandos. Las interfaces gráficas de usuario (GUIs por sus siglas en inglés) fueron desarrolladas inicialmente por XEROX y podrı́amos definirlas como una representación gráfica en la pantalla de la computadora de los programas, datos y objetos, ası́ como la interacción con ellos. Actualmente existen tres estilos comunes de GUIs que son; WYSIWYG (W hat Y ou S ee I s W hat Y ou Get), manipulación directa e interfaces de usuario basados en iconos. Las caracterı́sticas principales que tiene una interfaz gráfica son: 1. Posee un monitor gráfico de alta resolución. 2. Posee un dispositivo apuntador (comúnmente un ratón). 3. Sigue el paradigma de la interacción objeto-acción. 4. Promueve la consistencia de la interfaz entre programas. 5. Los usuarios pueden ver en la pantalla los gráficos y texto tal y como se verán impresos. 6. Permite la transferencia de datos entre programas. 7. Se pueden manipular directamente en la pantalla los objetos y la información. 8. Provee elementos de interfaz estándar como menús y diálogos. 9. Proporciona respuesta visual a las acciones del usuario. 10. Existen controles gráficos (widgets) para la selección e introducción de la información. 11. Proporciona flexibilidad en el uso de dispositivos de entrada (teclado/ratón.) Cuando el usuario utiliza una GUI necesita realizar fundamentalmente dos tareas; seleccionar un objeto y realizar una acción sobre dicho objeto donde no se requiere de un gran esfuerzo de abstracción, ya que esta forma de interactuar (conocida como objeto-acción) resulta más natural y próximo a su nivel mental. CAPÍTULO 2. INTRODUCCIÓN 2.2. 6 La arquitectura del Simulador El simulador que presentamos fue diseñado y construido usando un enfoque orientado a objetos, la reutilización de codigo es un concepto clave en nuestro diseño con lo que fue posible construir un sistema “ultraligero” con apenas 2,000 lineas de código escrito en java, aproximadamente. Las piezas elementales de nuestra construcción son dos clases fundamentales: “FrameDeSimulacion” y “ArregloDeSimulacion”. Una instancia de “FrameDeSimulacion” crea un espacio donde se muestra todo lo referente a la animación de la GUI. En tanto, una instancia de “ArregloDeSimulacion” puede funcionar como una pila o lista que contendra en forma ordenada la informacion necesaria para realizar una simulación sobre la grafica activa dado el algoritmo seleccionado. El resto de las clases con que se arma el sistema son las siguientes (véase la Figura: Diagrama de clases.): Lista Red FrameDeSimulacion Grafica 1 1 ArregloDeSimulacion 1 1 1 1 1 NegociosDePaquetes MotorSimulacion GeneraListaSimulacion() 1 0..* 1 Manejador Simulador Evento Agenda 1 1 1 0..* Figura 2.1: Diagrama de clases MiExperimento : FrameDeSimulacion accionPlay() miMotor : Simulador Lista : ArregloDeSimulacion L =generaLista() ListaSimulacion : NegociosDePaquetes agenda : Manejador e1 : Evento agenda=generaListaSimulacion() Return agenda Return L E=getPaquete(agenda) e1=GetPaqueteCoordenada(agenda) Return e1 Return E Return E repaint() Figura 2.2: Diagrama de Secuencia 1. Grafica: Representa la interconexión de los distintos elementos que intervienen en la simulación. CAPÍTULO 2. INTRODUCCIÓN 7 2. Simulador: Representa el distribuidor de eventos, también efectúa tareas de sincronia. 3. NegociosDePaquetes: Representa la rutina para la atención y filtración de eventos, de una maquina de estados. 4. Manejador: Representa un contenedor de los eventos que serán mostrados en un instante de tiempo determinado. 5. Evento: Representa un paquete de información intercambiada entre componentes. Una instancia de la clase FrameDeSimulacion llamada “miExperimento” la cual tiene asociada una grafica (Red de nodos y canales) a partir de la cual, dado un algoritmo previamente seleccionado, se genera una “Lista” de simulacion. “miMotor” es una instancia de la clase Simulador el cual tiene la funcion de organizar y secuenciar la información (paquetes y traza) que sera mostrada en el ”FrameDeSimulacion”. El metodo ListaSimulacion () toma la “Lista” y apartir de ella genera la “agenda” ayudandose del método getpaquete() que selecciona los eventos para cada instante t. El Simulador toma la agenda e invoca el método Repaint() el cuál ocaciona que se muestren los paquetes contenidos en la agenda. 2.3. Desarrollo y Creación de una GUI Cuando se pretende crear y desarrollar una GUI el resultado final no será satisfactorio si no se recurre a un cierto órden y metodologı́a para trabajar. Durante este proceso debemos de considerar forzosamente cuatro fases. 1. Reunir y analizar la información del usuario. Es decir, determinar y sintetizar qué tipo de usuarios van a usar el programa, que exigen los usuarios del programa, qué tareas van a realizar y como las van a realizar. 2. Diseñar la interfaz de usuario. Supone determinar la cantidad de componentes, su agrupación y su ubicación en el espacio, ası́ como determinar las acciones que se llevarán a cabo cuando el usuario interactúe con cada componente. Probablemente la parte medular de este proceso ya que es en esta fase donde se definen los objetivos de utilización del programa, las tareas del usuario, los objetos y acciones de la interfaz, los iconos, vistas, y representaciones visuales de los objetos, los menús de los objetos y ventanas. 3. Construir la interfaz de usuario. Es en esta fase donde se implementa todo lo discutido en la fase previa y se comienzan a crear versiones de la GUI. Es importante el ir guardando cada una de las versiones que se van obteniendo a fin de comparar y establecer metas y objetivos de la siguiente versión. 4. Validar la interfaz de usuario. Se deben realizar pruebas en lo que respecta a la utilización del producto preferentemente con el usuario final, en suma, es importante realizar un diseño que parta del usuario y no del sistema. CAPÍTULO 2. INTRODUCCIÓN 8 El desarrollo del simulador de eventos discretos se generó inicialmente utilizando un modelo previo programado en Tcl\Tk cuyo inconveniente principal radica en la gran dificultad que existe para ampliar el proyecto a partir del existente. Las ideas que tomamos de ese proyecto fueron principalmente el orden y distribución de los controles, menús y áreas de trabajo, obviamente personalizando y ampliando las posibilidades del usuario ayudándonos de las herramientas que nos proporciona Java. Capı́tulo 3 MANUAL DE USUARIO Para poder ejecutar el simulador, es necesario tener instalada alguna versión del jdk (superior al j2sdk-1 3). Si no se cuenta con el jdk, este cd cuenta con la versión j2sdk-1 4 1 01. Para instalar y configurar adecuadamente esta herramienta se deberán seguir las siguientes instrucciones: 1. Introducir el cd y abrir la carpeta j2sdk. 2. Dale doble click al ı́cono azul que se llama: j2sdk-1 4 1 01-windows-i586 3. Sigue las instrucciones de instalación. 4. Configuración del PATH y el CLASSPATH. Para Windows 98 Paso 1: Hacer una copia de respaldo del archivo autoexec.bat (por si las dudas). Paso 2: En el archivo autoexec.bat, añadir a la lı́nea que especifı́ca el path, lo siguiente: ;C:\j2sdk1.4.1 01\bin En el remoto caso que no tuvieras un path deberás crearlo ası́: path= C:\j2sdk1.4.1 01\bin (checa que aqui no hay un ; ) CAPÍTULO 3. MANUAL DE USUARIO 10 Paso3: Si YA TIENES una lı́nea con un classpath, añadirle lo siguiente: ;j2sdk1.4.1 01\lib\dt.jar;C:\j2sdk1.4.1 01\lib\htmlconverter.jar; C:\j2sdk1.4.1 01\lib\tools.jar;C:\j2sdk1.4.1 01\jre\lib\charset.jar; C:\j2sdk1.4.1 01\jre\lib\jaws.jar;C:\j2sdk1.4.1 01\jre\lib\jce.jar; C:\j2sdk1.4.1 01\jre\lib\jsse.jar;C:\j2sdk1.4.1 01\jre\lib\rt.jar; C:\j2sdk1.4.1 01\jre\lib\sunrsasign.jar OJO: El classpath DEBE comenzar con un punto seguido de un punto y coma asi: .; Ası́, el .; deberás insertarlo al inicio del classpath Paso 4: Si no tienes ninguna de las dos anteriores, debes crearlas. Solamente copia lo siguiente: path= C:\j2sdk1.4.1 01\bin classpath=.;j2sdk1.4.1 01\lib\dt.jar;C:\j2sdk1.4.1 01\lib\htmlconverter.jar; C:\j2sdk1.4.1 01\lib\tools.jar;C:\j2sdk1.4.1 01\jre\lib\charset.jar; C:\j2sdk1.4.1 01\jre\lib\jaws.jar;C:\j2sdk1.4.1 01\jre\lib\jce.jar; C:\j2sdk1.4.1 01\jre\lib\jsse.jar;C:\j2sdk1.4.1 01\jre\lib\rt.jar; C:\j2sdk1.4.1 01\jre\lib\sunrsasign.jar IMPORTANTE: Salva tu archivo con el mismo nombre: autoexec.bat y REINICIA el sistema. Para Windows 2000 o XP Paso 1: En Panel de Control selecciona Sistema. Dentro de Sistema abre la pestaña Opciones avanzadas Selecciona en la parte inferior Variables de Entorno En la ventana: ”Variables del sistema” selecciona la variable Path y pulsa el botón Modificar. En el cuadro de dialogo, añade en el campo valor lo siguiente: ;C:\j2sdk1.4.1 01\bin Paso 2: En la ventana ”Variables del sistema” pulsa el botón ”Nueva”. El nombre que debes dar es classpath y su valor: .;j2sdk1.4.1 01\lib\dt.jar;C:\j2sdk1.4.1 01\lib\htmlconverter.jar; C:\j2sdk1.4.1 01\lib\tools.jar;C:\j2sdk1.4.1 01\jre\lib\charset.jar; C:\j2sdk1.4.1 01\jre\lib\jaws.jar;C:\j2sdk1.4.1 01\jre\lib\jce.jar; C:\j2sdk1.4.1 01\jre\lib\jsse.jar;C:\j2sdk1.4.1 01\jre\lib\rt.jar; CAPÍTULO 3. MANUAL DE USUARIO 11 C:\j2sdk1.4.1 01\jre\lib\sunrsasign.jar Como en la página anterior, el classpath DEBE comenzar con un .; OJO: Sean cuidadosos con NO DEJAR espacios en blanco, con los ; y diagonales invertidas. Se supone que win2000 y XP no necesita la reinicialización del sistema, pero NO ESTÁ POR DEMÁS. 3.1. Partes de la GUI El diseño de la interfaz del simulador que se desarrlló durante este proyecto parte de un diseño anterior programado en Tcl\Tk. Nuestra interfaz cuenta con 4 elementos principales que son; Barra de menús. Barra de herramientas. Area de texto. Area gráfica. Figura 3.1: Simulador de Eventos Discretos Las barras de menu y herramientas respectivamente, proporcionan al usuario todo lo necesario para introducir información al programa, mientras que las áreas de texto y gráfica responden visualmente a esta información. La barra de menús cuenta con 3 opciones que pueden ser accedidas con el botón izquierdo del mouse. CAPÍTULO 3. MANUAL DE USUARIO 12 Menú Archivo. Menú Edición. Menú Ayuda. 3.1.1. Menú Archivo Al acceder a este menú se despliega una lista con los submenús Nuevo, Abrir Gráfica, Abrir Algoritmo, Guardar, Guardar como, Cerrar y Salir. Figura 3.2: Menú Archivo. Nuevo Esta función crea una nueva ventana de simulación cada vez que se selecciona. Si existe una gráfica abierta, y se quiere utilizar ésta función el programa pregunta si se quiere guardar la gráfica previa, haciendo esto la pantalla del simulador aparece como en la figura 1 Abrir gráfica Este submenú permite al usuario desplegar una gráfica en el área correspondiente creada con anterioridad y es sobre esta gráfica donde el usuario observará la simulación de acuerdo al algoritmo que haya seleccionado. Esta caja de diálogo presenta un filtro de apertura de archivos que forza al usuario elegir solamente archivos que tengan extensión *.gra. Abrir Algoritmo . Es con esta selección que el usuario podrá realizar una simulación de algoritmos de enrutamiento con base en una gráfica cargada en el área gráfica. A diferencia de la versión anterior del simulador programado en Tcl\Tk, en donde solo se podı́a simular a partir de 6 algoritmos cargados en la interfaz, nuestro simulador permite cargar cualquier algoritmo que resida en la máquina, expandiendo la posibilidad de que el investigador desarrolle un nuevo algoritmo y no necesite modificar el código de la interfaz para poder hacer una simulación. CAPÍTULO 3. MANUAL DE USUARIO 13 Figura 3.3: Diálogo que muestra la apertura de una gráfica Guardar y Guardar como Estas opciones permiten guardar solamente archivos con extensión *.gra (gráficas). Si se utiliza la opción Guardar se guarda toda la información correspondiente a la gráfica que el usuario tenga en pantalla en ese momento. Si es una gráfica nueva la que se va a guardar la opción que aparece es Guardar como. La opción Guardar como guarda (si ası́ se prefiere) la gráfica con un nombre distinto al actual, al hacerlo no se pierde el nombre que se tenı́a anteriormente, por ejemplo, si se tiene una archivo llamado A1.gra y al utilizar esta opción se da el nombre de A2.gra, ya se tienen dos archivos guardados (A1.gra y A2.gra). Figura 3.4: Diálogo para guardar una gráfica con extensión *.gra. CAPÍTULO 3. MANUAL DE USUARIO 14 Cerrar y Salir La opción Cerrar únicamente cierra la gráfica que en ése momento esté abierta en el panel, pero sin salir del Simulador. Si la gráfica tuvo alguna modificación y no se guardo antes de elegir esta opción, aparece una caja de diálogo que informa de esta situación. La opción Salir cierra toda la aplicación y también ofrece la opción al usuario de guardar una gráfica modificada. Figura 3.5: Guardar cambios antes de salir. 3.2. Menú Edición Es con este menú con el que el usuario puede crear y manipular una gráfica. Al acceder a este menú se despliega una lista con los submenús Agregar nodo, Enlazar nodo,y Mover nodo. Figura 3.6: Menú Edición. Agregar Nodo Esta función permite insertar cualquier número de nodos en el área gráfica. Esta acción estará habilitada todo el tiempo que el usuario requiera de estar pintando nodos, es decir, no CAPÍTULO 3. MANUAL DE USUARIO 15 es necesario oprimir este menú item cada vez que se desee pintar un nodo en el área gráfica. Esta acción se deshabilita al utilizar cualquiera de las otras funciones disponibles. Si por alguna razón se quisiera eliminar un nodo, esto se puede realizar simplemente posisionándose sobre el nodo a eliminar y haciendo click con el botón derecho del mouse. Figura 3.7: Menú Item para agregar nodos a la gráfica Enlazar nodo Ya teniendo el número correcto de nodos insertados en el área gráfica, la siguiente acción que podrı́amos realizar serı́a enlazarlos. La función Enlazar nodo crea un canal de comunicación entre nodos. La forma en que se utiliza es la siguiente: Se habilita la función dando click en el menú item correspondiente. Se selecciona el nodo origen (el cuál se pondrá de color verde al ser seleccionado) y después se selecciona el nodo destino. Al hacer ésto, el canal de comunicación se crea (color rojo). No es necesario dejar oprimido el botón del mouse para pintar el enlace. De la misma forma que la función anterior, ésta función queda habiitada hasta que se elija alguna otra. Figura 3.8: La función Enlazar nodo permite crear canales entre los nodos CAPÍTULO 3. MANUAL DE USUARIO 16 Mover nodo La función Mover nodo permite el reacomodo de los nodos insertados. Al habilitar la función (dando click en el menú correspondiente) es posible mover los nodos de un lugar a otro de la gráfica, dando click a uno y moverlo (sin soltar el botón) hasta donde se quiera.Ésta función queda habiitada hasta que se elija alguna otra. Figura 3.9: Como reacomodar nodos con la función Mover nodo 3.2.1. Menú Simulación Cuando el usuario haya terminado de construir la gráfica, el siguiente paso es simular los algoritmos sobre dicha gráfica. Para esto se requiere de utilizar las funciones del menú Simulación. Cabe resaltar que la versión actual del simulador tiene precargado un archivo de simulación y no es posible simular aún ningún algoritmo. Esta función estará habilitada enla siguiente versión. Figura 3.10: Funciones accesibles del menú Simulador Simular y Pausa El inicio de una simulación se realiza dando click al menú item Simular. Si por alguna razón queremos pausar la simulación, se deberá dar click al menú item con el mismo nombre (Pausa). CAPÍTULO 3. MANUAL DE USUARIO 17 Para reactivar la simulación se debe dar click nuevamente al menú Simular. Figura 3.11: Menú item para iniciar la simulación Detener Con esta opción se para por completo la simulación. Después de haber dado click a este menú item, el proceso de simulación se para por completo y es posible reeditar la gráfica. Para volver a iniciar la simulación habrı́a que oprimir nuevamente el menu Simular y la simulación arrancarı́a desde un principio. Figura 3.12: Menú item para detener la simulación 3.3. Menú Ayuda Simplemente despliega la versión del simulador. CAPÍTULO 3. MANUAL DE USUARIO 18 Figura 3.13: Muestra la versión del simulador 3.4. Barra de Herramientas La barra de herramientas presenta un conjunto de botones que realiza las mismas tareas que los menú items explicados en la sección anterior. Figura 3.14: Barra de herramientas La siguiente lista asocia los menú items con los botones que se muestran en la figura 2.13 (y por supuesto en el simulador) de izquierda a derecha. No se profundiza en la explicación de cada botón puesto que las funciones que realizan ya se explicaron en la sección anterior. Crear nodo Mover nodo Enlazar nodo Simular Alto Pausa Barra de velocidad. Esta barra controla la velocidad de la simulación Capı́tulo 4 MANUAL TÉCNICO El presente capitúlo tiene como principal objetivo el de proporcionar información técnica de la forma en que fue construida la Interfas Graficade Usuario (GUI), para facilitar el trabajo de quien tenga la intencion de realizar mejoras en ella. A continuacion se presentara el codigo de la GUI, conformada por 50 clases divididas en 4 paquetes. Uno de los principales objetivos de le presente versión de la GUI es que ésta permita le inclusión de mejoras de forma sencilla (motivo por el cuál se realizó utilizando el paradigma de la POO. 4.1. Paquete archivos El choro de la clase archivo 4.1.1. Clase cArchivo package simulador.archivos; import java.util.*; import java.io.*; public class cArchivo { public cArchivo(){ } public ArrayList leerArchivo(String ruta)throws IOException{ ArrayList leer=new ArrayList(); String cache; BufferedReader entrada= new BufferedReader( new FileReader(ruta)); while((cache=entrada.readLine())!=null){ leer.add(cache); } entrada.close(); return leer; } public void escribirArchivo(String ruta,ArrayList datos)throws IOException{ String cache; CAPÍTULO 4. MANUAL TÉCNICO BufferedWriter salida= new BufferedWriter(new FileWriter(ruta)); for(int i=0; i<datos.size(); i++){ cache=(String)datos.get(i); salida.write(cache); } salida.close(); } } 4.2. Paquete elementos 4.2.1. Clase cCanal package simulador.elementos; import java.awt.*; public class cCanal { private int peso; private Color color; private cNodo destino; public cCanal(int peso, cNodo destino) { setPeso(peso); setDestino(destino); } public void setPeso(int peso) { this.peso = peso; } public void setColor(Color color) { this.color = color; } public void setDestino(cNodo destino) { this.destino = destino; } public int getPeso() { return this.peso; } public Color getColor() { return this.color; 20 CAPÍTULO 4. MANUAL TÉCNICO } public cNodo getDestino() { return this.destino; } } 4.2.2. Clase cNodo package simulador.elementos; import simulador.negocios.*; import java.util.*; import java.awt.*; public class cNodo { private private private private private int x; int y; int iD; Color color; cNCanal canal = new cNCanal(); public cNodo(int x, int y, int iD) { setX(x); setY(y); setID(iD); setColor(Color.BLUE); } public cNodo(int x, int y, int iD, Color color) { setX(x); setY(y); setID(iD); setColor(color); } public void setColor(Color color) { this.color = color; } public Color getColor() { return this.color; } public void setCanal(cNCanal canal) { cNCanal aux = canal; 21 CAPÍTULO 4. MANUAL TÉCNICO if (canal.equals(null)) { aux = new cNCanal(); } this.canal = aux; } public cNCanal getCanal() { return this.canal; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } public void setID(int iD) { this.iD = iD; } public int getX() { return this.x; } public int getY() { return this.y; } public int getID() { return this.iD; } } 4.2.3. Clase cPaquete package simulador.elementos; import java.awt.*; public class cPaquete extends Component { private Color color; private int idP; private int instanteEnvio; private cNodo origen; private cNodo destino; 22 CAPÍTULO 4. MANUAL TÉCNICO private String mensaje; public cPaquete() { } public cPaquete(int idP, String mensaje) { this.setSize(20, 20); this.setIdP(idP); this.setColor(Color.BLUE); this.setMensaje(mensaje); } public cPaquete(Color color, int idP, String mensaje) { this(idP, mensaje); this.setColor(color); this.setMensaje(mensaje); } public cPaquete(Color color, int idP, String mensaje, cNodo origen, cNodo destino) { this(color, idP, mensaje); this.setOrigen(origen); this.setdestino(destino); } public cPaquete(Color color, int idP, String mensaje, cNodo origen, cNodo destino, int tEnvio) { this(color, idP, mensaje, origen, destino); this.setInstanteEnvio(tEnvio); } void setInstanteEnvio(int tEnvio) { this.instanteEnvio = tEnvio; } void setIdP(int idP) { this.idP = idP; } void setColor(Color color) { this.color = color; } void setOrigen(cNodo origen) { this.origen = origen; 23 CAPÍTULO 4. MANUAL TÉCNICO } void setdestino(cNodo destino) { this.destino = destino; } void setMensaje(String mensaje) { this.mensaje = mensaje; } public int getIdP() { return this.idP; } public Color getColor() { return this.color; } public cNodo getOrigen() { return this.origen; } public cNodo getDestino() { return this.destino; } public String getMensaje() { return this.mensaje; } public int getIstanteEnvio() { return this.instanteEnvio; } } 4.2.4. Clase cPaqueteAux package simulador.elementos; import java.awt.*; public class cPaqueteAux { private Color color; private int x; private int y; public cPaqueteAux(int x,int y,Color color) { 24 CAPÍTULO 4. MANUAL TÉCNICO this.setColor(color); this.setX(x); this.setY(y); } public void setColor(Color color){ this.color=color; } public void setX(int x){ this.x=x; } public void setY(int y){ this.y=y; } public Color getColor(){ return this.color; } public int getX(){ return this.x; } public int getY(){ return this.y; } } 4.2.5. Clase cPaqueteCoordenadas package simulador.elementos; public class cPaqueteCoordenadas { cPaquete paquete; float coordenadas[ ][ ]; public cPaqueteCoordenadas(cPaquete paquete, float [ ][ ] coordenadas ){ this.setPaquete(paquete); this.setCoordenadas(coordenadas); } public void setPaquete(cPaquete paquete){ this.paquete=paquete; 25 CAPÍTULO 4. MANUAL TÉCNICO 26 } public void setCoordenadas(float [ ][ ] coordenadas){ this.coordenadas=coordenadas; } public cPaquete getPaquete(){ return this.paquete; } public float [ ][ ] getCoordenadas(){ return this.coordenadas; } } 4.3. Paquete Interfaces 4.3.1. Clase AccionBotonSimular package simulador.interfaces; import import import import import import import java.awt.event.*; java.awt.*; simulador.elementos.*; simulador.negocios.*; simulador.archivos.*; java.io.*; java.util.*; public class AccionBotonSimular implements ActionListener { SimuladorFrame f; public AccionBotonSimular(SimuladorFrame f) { this.f = f; } public void actionPerformed(ActionEvent e) { f.habilitarBarraEdicion(false); f.accionPlay(); } } ESTA CLASE AUN PUEDE SER MODIFICADA POR LO MODIFICACION DEL BOTON STOP CAPÍTULO 4. MANUAL TÉCNICO 4.3.2. Clase cIContenedor de Nodos package simulador.interfaces; import import import import import import import import import java.awt.*; java.awt.event.*; javax.swing.*; simulador.negocios.*; simulador.elementos.*; simulador.archivos.*; java.util.*; java.io.*; java.util.LinkedList; public class cIContenedorDeNodos extends JPanel { public static cNodo auxiliar; private cNNodos oNNodo; private SimuladorFrame f; public static ArrayList paquetesValidos = new ArrayList(); public cIContenedorDeNodos(SimuladorFrame f) { this.f = f; this.iniciaEventos(); this.oNNodo = new cNNodos(); } public cIContenedorDeNodos(SimuladorFrame f, cNNodos oNNodo) { this.f = f; this.oNNodo = oNNodo; this.iniciaEventos(); } public void paint(Graphics g) { System.out.println(”pintando ”); cNNodos aux = oNNodo; cNNodos aux1 = oNNodo; cNodo nodoAux; cNodo nodoAdya; ArrayList paquetes=paquetesValidos; if (aux == null) { return; } for (int i = 0; i ¡aux.size(); i++) { nodoAux = (cNodo) aux.get(i); g.setColor(nodoAux.getColor()); g.fillRoundRect(nodoAux.getX(), nodoAux.getY(), 16, 16, 80, 80); 27 CAPÍTULO 4. MANUAL TÉCNICO g.drawString( + nodoAux.getID(), nodoAux.getX(), nodoAux.getY()); } for (int j = 0; j ¡aux.size(); j++) LinkedList auxAdya = ( (cNodo) aux1.get(j)).getCanal(); nodoAux = (cNodo) aux1.get(j); for (int k = 0; k ¡auxAdya.size(); k++) nodoAdya = ( (cCanal) auxAdya.get(k)).getDestino(); g.setColor(Color.red); g.drawLine(nodoAux.getX() + 8, nodoAux.getY() + 8, nodoAdya.getX() + 8, nodoAdya.getY() + 8); } } for (int i = 0; i ¡this.paquetesValidos.size(); i++) { cPaqueteAux paquete = (cPaqueteAux)paquetes.get(i); g.setColor(paquete.getColor()); g.fillRoundRect(paquete.getX(), paquete.getY(), 10, 10, 0, 0); } } private void iniciaEventos() { this.addMouseListener(new EventosMouseContenedorDeNodos(oNNodo, f)); this.addMouseMotionListener(new MouseMotionAdapter() { private cNNodos nodo; public void mouseDragged(MouseEvent e) { if (f.btnMover.isSelected()) { if (auxiliar != null) { auxiliar.setColor(new Color(30, 176, 26)); auxiliar.setX(e.getX()); auxiliar.setY(e.getY()); f.repaint(); } } } }); } public void setPaquetes(ArrayList paquetes) { this.paquetesValidos = paquetes; } } 28 CAPÍTULO 4. MANUAL TÉCNICO 4.3.3. Clase SimuladorFrame AboutBox package simulador.interfaces; import import import import java.awt.*; java.awt.event.*; javax.swing.*; javax.swing.border.*; public class SimuladorFrame AboutBox extends JDialog implements ActionListener { JPanel panel1 = new JPanel(); JPanel panel2 = new JPanel(); JPanel insetsPanel1 = new JPanel(); JPanel insetsPanel2 = new JPanel(); JPanel insetsPanel3 = new JPanel(); JButton button1 = new JButton(); JLabel imageLabel = new JLabel(); JLabel label1 = new JLabel(); JLabel label2 = new JLabel(); JLabel label3 = new JLabel(); JLabel label4 = new JLabel(); ImageIcon image1 = new ImageIcon(); BorderLayout borderLayout1 = new BorderLayout(); BorderLayout borderLayout2 = new BorderLayout(); FlowLayout flowLayout1 = new FlowLayout(); GridLayout gridLayout1 = new GridLayout(); String product = ”Simulador”; String version = ”1.0”; String copyright = Çopyright (c) 2004”; String comments = ”Simulador de Eventos Discretos”; public SimuladorFrame AboutBox(Frame parent) { super(parent); enableEvents(AWTEvent.WINDOW EVENT MASK); try { jbInit(); } catch(Exception e) { e.printStackTrace(); } } private void jbInit() throws Exception { image1 = new ImageIcon (simulador.interfaces.SimuladorFrame.class.getResource(.about.png”)); imageLabel.setIcon(image1); this.setTitle(.About”); 29 CAPÍTULO 4. MANUAL TÉCNICO panel1.setLayout(borderLayout1); panel2.setLayout(borderLayout2); insetsPanel1.setLayout(flowLayout1); insetsPanel2.setLayout(flowLayout1); insetsPanel2.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); gridLayout1.setRows(4); gridLayout1.setColumns(1); label1.setText(product); label2.setText(version); label3.setText(copyright); label4.setText(comments); insetsPanel3.setLayout(gridLayout1); insetsPanel3.setBorder(BorderFactory.createEmptyBorder(10, 60, 10, 10)); button1.setText(.Ok”); button1.addActionListener(this); insetsPanel2.add(imageLabel, null); panel2.add(insetsPanel2, BorderLayout.WEST); this.getContentPane().add(panel1, null); insetsPanel3.add(label1, null); insetsPanel3.add(label2, null); insetsPanel3.add(label3, null); insetsPanel3.add(label4, null); panel2.add(insetsPanel3, BorderLayout.CENTER); insetsPanel1.add(button1, null); panel1.add(insetsPanel1, BorderLayout.SOUTH); panel1.add(panel2, BorderLayout.NORTH); setResizable(true); } protected void processWindowEvent(WindowEvent e) { if (e.getID() == WindowEvent.WINDOW CLOSING) { cancel(); } super.processWindowEvent(e); } void cancel() { dispose(); } public void actionPerformed(ActionEvent e) { if (e.getSource() == button1) { cancel(); } } } 30 CAPÍTULO 4. MANUAL TÉCNICO 4.3.4. Clase cNCanal package simulador.negocios; import java.util.LinkedList; import simulador.elementos.*; public class cNCanal extends LinkedList { public cNCanal() { } public void agregar(cNodo nodo, int peso) { this.add(new cCanal(peso, nodo)); } public void imprime(int nodo) { cCanal canal; for (int i = 0; i ¡this.size(); i++) { canal = (cCanal)this.get(i); System.out.println(nodo + ¿”+ canal.getDestino().getID()); } } public boolean existeCanal(int idNodo) { boolean ban = false; if (this.size() != 0) { for (int i = 0; i ¡this.size(); i++) { cCanal canal = (cCanal)this.get(i); if (canal.getDestino().getID() == idNodo) { ban = true; break; } } } return ban; } } 4.3.5. Clase cNNodos package simulador.negocios; import simulador.elementos.*; import java.util.LinkedList; public class cNNodos extends LinkedList { 31 CAPÍTULO 4. MANUAL TÉCNICO public static int iD = 0; public void agregar(int x, int y) { this.add(new cNodo(x, y, iD++)); } public boolean noEncimar(int x, int y) { cNodo nodo; boolean bandera = false; for (int i = 0; i ¡this.size(); i++) { nodo = (cNodo)this.get(i); if (nodo.getX() - 16 ¡x && (nodo.getX() + 32) ¿x && nodo.getY() - 16 ¡y && (nodo.getY() + 32) ¿y) { bandera = true; } } return bandera; } public cNodo existe(int x, int y) { cNodo nodo; cNodo nodoARegresar = null; for (int i = 0; i ¡this.size(); i++) { nodo = (cNodo)this.get(i); if (nodo.getX() - 16 ¡x && (nodo.getX() + 32) ¿x && nodo.getY() - 16 ¡y && (nodo.getY() + 32) ¿y) { nodoARegresar = nodo; } } return nodoARegresar; } public cNodo existe(int numero) { cNodo nodo; cNodo nodoARegresar = null; for (int i = 0; i ¡this.size(); i++) { nodo = (cNodo)this.get(i); if (nodo.getID() == numero) { nodoARegresar = nodo; } } return nodoARegresar; } public void eliminaNodo(int idNodo) { cNodo nodo; for (int i = 0; i ¡this.size(); i++) { nodo = (cNodo)this.get(i); 32 CAPÍTULO 4. MANUAL TÉCNICO if (nodo.getID() == idNodo) { this.remove(i); return; } } } public void eliminaCanal(int idNodo) { cNodo nodo; cNodo revisarRelacion; cCanal canal; for (int i = 0; i ¡this.size(); i++) { nodo = (cNodo)this.get(i); for (int j = 0; j ¡nodo.getCanal().size(); j++) { canal = ( (cCanal) (nodo.getCanal().get(j))); revisarRelacion = canal.getDestino(); if (revisarRelacion.getID() == idNodo) { nodo.getCanal().remove(j); } } } } public void imprime() { cNodo nodo; for (int i = 0; i ¡this.size(); i++) { nodo = (cNodo)this.get(i); System.out.println(nodo.getID() + + nodo.getX() + + nodo.getY()); } } } 4.3.6. Clase cNPaquete package simulador.negocios; import import import import simulador.elementos.*; java.io.*; java.util.*; java.awt.*; public class cNPaquete extends ArrayList { public cNPaquete() { } public ArrayList generaListaPaquetes() { ArrayList simulacion = new ArrayList(); 33 CAPÍTULO 4. MANUAL TÉCNICO 34 cNPaqueteCoordenadas listaPaqueteCoordenadas = new cNPaqueteCoordenadas(); cPaqueteCoordenadas paqueteCoordenadas; cPaquete aux; float[][] coordenadas; for (int j = 1; j ¡= ((cPaquete)this.get (this.size()-1)).getIstanteEnvio(); j++) { for (int i = 0; i ¡this.size(); i++) { aux = (cPaquete)this.get(i); if (aux.getIstanteEnvio() == j) { coordenadas=this.calculaRecta(aux.getOrigen().getX(), aux.getOrigen().getY(),aux.getDestino().getX(),aux.getDestino().getY()); paqueteCoordenadas = newcPaqueteCoordenadas(aux, coordenadas); listaPaqueteCoordenadas.agregar(paqueteCoordenadas); } } simulacion.add(listaPaqueteCoordenadas); listaPaqueteCoordenadas = new cNPaqueteCoordenadas(); } return simulacion; } public float[][] calculaRecta(int x1, int y1, int x2, int y2) { float coordenadas[][] = new float[2][100]; for (int i = 0; i ¡coordenadas[0].length; i++) { coordenadas[0][i] = x1 + ( (float) (i) / 100) * (x2 - x1); coordenadas[1][i] = y1 + ( (float) (i) / 100) * (y2 - y1); } return coordenadas; } public ArrayList getCabecera(ArrayList archivo) { ArrayList cabecera = new ArrayList(); String g = new String(); int i = 0; while (! (g = (String) archivo.get(i)).equals(”inicio”)) { cabecera.add(g); i++; } return cabecera; } public void getPaquetes(ArrayList lines, cNNodos nodos) { cPaquete paqueteAux; int idProceso = 0; int nodoOrigen = 0; int nodoDestino = 0; int instEnvio = 0; int instRecep = 0; CAPÍTULO 4. MANUAL TÉCNICO int i = 0; int j = 0; char[] charAux; String aux = new String(); String num = new String(); String tipoDePaquete = new String(); String traza = new String(); Color colorAux; while (j¡lines.size()&&!(aux = (String) lines.get(j)).equals(”inicio”)) { j++; } j++; while (! (aux = (String) lines.get(j)).equals(”fin”) && j ¡lines.size()) { if (aux.length() ¿0) { charAux = ( (String) lines.get(j)).toCharArray(); while (Character.isDigit(charAux[i])) { num += charAux[i++]; } instEnvio = Integer.parseInt(num); num = new String(); i++; while (Character.isDigit(charAux[i])) { num += charAux[i++]; } nodoOrigen = Integer.parseInt(num); num = new String(); i++; while (Character.isDigit(charAux[i])) { num += charAux[i++]; } idProceso = Integer.parseInt(num); num = new String(); i++; while (Character.isLetter(charAux[i])) { num += charAux[i++]; } tipoDePaquete = new String(num); num = new String(); i++; while (Character.isDigit(charAux[i])) { num += charAux[i++]; } instRecep = Integer.parseInt(num); num = new String(); i++; while (Character.isDigit(charAux[i])) { num += charAux[i++]; } 35 CAPÍTULO 4. MANUAL TÉCNICO nodoDestino = Integer.parseInt(num); num = new String(); i++; while (i ¡charAux.length) { num += charAux[i++]; } traza = new String(num); num = new String(); i++; } colorAux = generarColor(tipoDePaquete); cNodo origen = nodos.existe(nodoOrigen); if (origen != null) { cNodo destino = nodos.existe(nodoDestino); if (destino != null) { this.add(new cPaquete(colorAux,idProceso, traza, origen, destino,instEnvio)); } } i = 0; j++; } } Color generarColor(String tipoDePaquete) { Color color = new Color(0, 0, 0); if (tipoDePaquete.equals(”DESPIERTA”)) { color = Color.RED; } if (tipoDePaquete.equals(ÇONECTA”)) { color = Color.PINK; } if (tipoDePaquete.equals(”INICIA”)) { color = Color.CYAN; } if (tipoDePaquete.equals(”PRUEBA”)) { color = Color.MAGENTA; } if (tipoDePaquete.equals(RECHAZA”)) { color = Color.ORANGE; } if (tipoDePaquete.equals(REPORTE”)) { color = Color.YELLOW; } return color; } public void pintaPaquetes() { 36 CAPÍTULO 4. MANUAL TÉCNICO 37 cPaquete paquete; for (int j = 1; j ¡= ((cPaquete) textbfthis.get(this.size() - 1)).getIstanteEnvio(); j++) { System.out.println(”intstante de envio: ”+ j); for (int i = 0; i ¡this.size(); i++) { paquete = (cPaquete)this.get(i); if (paquete.getIstanteEnvio() == j) { System.out.println(”idPaquete:”+ paquete.getIdP() + ”, ”+ ”nodoO:”+ paquete.getOrigen().getID() + ”, ”+ ”nodoD:”+ paquete.getDestino().getID() + ”, ”+ ”instEnvio:”+ paquete.getIstanteEnvio() + ”,”+ ”traza:”+ paquete.getMensaje() + ”, ”+ Çolor”+ paquete.getColor().toString()); } } } } } 4.3.7. Clase cNPaqueteCoordenadas package simulador.negocios; import java.util.*; import simulador.elementos.*; public class cNPaqueteCoordenadas extends ArrayList { public cNPaqueteCoordenadas() { } public void agregar(cPaquete paquete, float[][] coordenadas) { this.add(new cPaqueteCoordenadas(paquete, coordenadas)); } public void agregar(cPaqueteCoordenadas paqueteCoordenadas) { this.add(paqueteCoordenadas); } } 4.3.8. Clase DebugHelper package simulador.negocios; import java.io.StringWriter; import java.io.PrintWriter; import java.util.StringTokenizer; CAPÍTULO 4. MANUAL TÉCNICO 38 import java.text.DateFormat; import java.text.SimpleDateFormat; public class DebugHelper { private static boolean debugging = true; public final static int ALWAYS = 1; public final static int OPERATION; static{ OPERATION = 1; } public final static int DEBUG = 0xDEB09; public DebugHelper(){ } public static void out(String msg){ if (debugging){ System.out.println(msg); } } public static void out(String msg, int nivel){ switch(nivel){ case ALWAYS: System.out.println(”n ¡INFO¿¡”+ +))¡”+getClassMethodAndLine() +)) n ”+ msg ); break; case DEBUG: printDebugInfo(msg); } } private static void printDebugInfo( String message ){ if ( debugging ){ System.out.println(”n ¡Debug¿¡”+ +))¡”+getClassMethodAndLine() +)) n ”+ message ); } } getCurrentTime() getCurrentTime() private final static DateFormat dateFormatter = new SimpleDateFormat( ”dd-MMMyy HH:mm:ss”); private static String getCurrentTime(){ return dateFormatter.format( new java.util.Date() ); } CAPÍTULO 4. MANUAL TÉCNICO 39 private static String getClassMethodAndLine(){ return getCurrentLine( getStackTrace()); } private static String getStackTrace() { Throwable t = new Exception(); StringWriter sout = new StringWriter(); PrintWriter out = new PrintWriter( sout ); t.printStackTrace( out ); return sout.toString(); } private static String getCurrentLine( String stackTrace ){ StringTokenizer tokenizer = new StringTokenizer( tem.getProperty(”line.separator”)); tokenizer.nextToken(); tokenizer.nextToken(); tokenizer.nextToken(); tokenizer.nextToken(); tokenizer.nextToken(); String line = tokenizer.nextToken(); return line.substring( line.indexOf(.at”) + 3 ); } stackTrace, } Nota en la linea 76, 92 faltan una par de barras que todabia no se como poner 4.3.9. Clase EventosMouseContenedorDeNodos package simulador.negocios; import import import import import java.awt.event.*; java.awt.*; java.io.*; simulador.interfaces.*; simulador.elementos.*; public class EventosMouseContenedorDeNodos extends MouseAdapter { private cNCanal adyacencias = new cNCanal(); private cNNodos lista; private cNodo nodo, nodo1; private SimuladorFrame f; public EventosMouseContenedorDeNodos(cNNodos lista, SimuladorFrame f) { this.lista = lista; this.f = f; this.f.repaint(); Sys- CAPÍTULO 4. MANUAL TÉCNICO } public boolean presionado = false; public void mousePressed(MouseEvent e) { cIContenedorDeNodos.auxiliar = lista.existe(e.getX(), e.getY()); } public void mouseReleased(MouseEvent e) { /*Accion a realizar si el boton mover esta seleccionado*/ if (f.btnMover.isSelected() && cIContenedorDeNodos.auxiliar != null) { //regresar el nodo a color cIContenedorDeNodos.auxiliar.setColor(Color.blue); //azul cuando se termina f.repaint(); //de mover f.MODIFICADO = true; } /*Accion a realizar si esta seleccionado el boton nuevo Nodo*/ if (f.btnNodo.isSelected()) { if (lista.noEncimar(e.getX(), e.getY()) && e.getButton() == 1) { return; } if (e.getButton() == 1) { lista.agregar(e.getX(), e.getY()); f.repaint(); f.MODIFICADO = true; } if (e.getButton() == 3) { nodo = lista.existe(e.getX(), e.getY()); if (nodo != null) { lista.eliminaNodo(nodo.getID()); lista.eliminaCanal(nodo.getID()); f.repaint(); f.MODIFICADO = true; } } } /*accion a realizar si esta seleccionado el boton unir Nodo*/ if (f.btnEnlace.isSelected()) { if (e.getButton() == 1) { if (!presionado) { nodo = lista.existe(e.getX(), e.getY()); if (nodo != null) { nodo.setColor(new Color(30, 176, 26)); presionado = true; f.repaint(); f.MODIFICADO = true; } } 40 CAPÍTULO 4. MANUAL TÉCNICO 41 else { /*si se entra a este else quiere decir que ya se tiene el nodo origen seleccionado*/ nodo1 = lista.existe(e.getX(), e.getY()); if (nodo1 != null) { if (! (nodo.getCanal().existeCanal(nodo1.getID())) && nodo.getID() != nodo1.getID()) { /*validando que si ya existe la adyacencia no se genere una adyacencia duplicada, la segunda validacion es para evitar que se hagan adyacencias de un nodo consigo mismo*/ nodo.getCanal().agregar(nodo1, 0); /*se genera una adyacencia bidireccional*/ nodo1.getCanal().agregar(nodo, 0); } presionado = false; nodo.setColor(Color.BLUE); f.repaint(); f.MODIFICADO = true; } } } if (e.getButton() == 3) { if (!presionado) { nodo = lista.existe(e.getX(), e.getY()); if (nodo != null) { nodo.setColor(new Color(30, 176, 26)); presionado = true; f.repaint(); } } else { /*si se entra a este else quiere decir que ya se tiene el nodo origen seleccionado*/ nodo1 = lista.existe(e.getX(), e.getY()); if (nodo1 != null) { if ((nodo.getCanal().existeCanal(nodo1.getID())))//.existeAdya(nodo.adyacencias, nodo1.idNodo)) { /*validando que existe la adyacencia */ lista.eliminaCanal(nodo1.getID()) } presionado = false; nodo.setColor(Color.BLUE); f.repaint(); } } } } } CAPÍTULO 4. MANUAL TÉCNICO } checar en el codigo real la linea 145,146 4.3.10. Clase Filtro package simulador.negocios; import javax.swing.filechooser.*; import java.io.*; public class Filtro extends javax.swing.filechooser.FileFilter { public Filtro() { } public boolean accept(File f) { String extension = ; if (f.getPath().lastIndexOf(’.’) ¿0) extension=f.getPath().substring(f.getPath().lastIndexOf(’.’)+1).toLowerCase(); if (extension != ) return extension.equals(”gra”); else return f.isDirectory(); } public String getDescription() { return .Archivo de simulación (*.gra)”; } } falta el simbolo de mayor q en la linea 46 y comillas en la liena 50 4.3.11. Clase ManejoDeArchivosEntrada package simulador.negocios; import java.io.*; import java.util.*; import simulador.elementos.*; public class ManejoDeArchivosEntrada { private cNNodos lista; private cNCanal listAdya = new cNCanal(); DataInputStream adyacenciasI; DataInputStream coordenadasI; 42 CAPÍTULO 4. MANUAL TÉCNICO public ManejoDeArchivosEntrada(String path1, String path2, cNNodos lista) throwsIOException { DebugHelper.out(”ManejoDeArchivosEntrada path1: ”+path1); DebugHelper.out(”ManejoDeArchivosEntrada path2: ”+path2); this.lista = lista; DebugHelper.out(”ManejoDeArchivosEntrada lista: ”+this.lista); adyacenciasI = new DataInputStream(new BufferedInputStream(new FileInputStream(path1))); coordenadasI = new DataInputStream(new BufferedInputStream(new FileInputStream(path2))); leeCoordenadas(); leeAdyacencias(); } public void archivoDeEntrada(cNNodos aux, int num) throws IOException, EOFException { if (aux == null) { return; } int i = num; if (aux.size() == 0) { leeAdyacencias(); leeCoordenadas(); return; } } public void leeAdyacencias() throws IOException { String g = new String(); cNodo nodo; cNodo nodo1; cNCanal canal; cNCanal canal1; int nNodo, peso; int iter = 0; while ( (g = adyacenciasI.readLine()) != null) { int i = 0; String adyaAux = new String(); String pesoAux = new String(); char[] charAux = g.toCharArray(); if (charAux.length != 0) { while (i ¡charAux.length) { while (i ¡g.length() && Character.isDigit(charAux[i])) { adyaAux = adyaAux + charAux[i]; i++; } i++; while (i ¡g.length() && Character.isDigit(charAux[i])) { 43 CAPÍTULO 4. MANUAL TÉCNICO pesoAux = pesoAux + charAux[i]; i++; } nNodo = Integer.parseInt(adyaAux); peso = Integer.parseInt(pesoAux); adyaAux = new String(); pesoAux= new String(); nodo = this.lista.existe(nNodo); if (nodo != null) { nodo1 = this.lista.existe(iter); if (nodo1 != null) { if (!nodo.getCanal().existeCanal(nodo1.getID()) && nodo.getID() != nodo1.getID()) { canal= nodo.getCanal(); canal1=nodo1.getCanal(); canal1.agregar(nodo, peso); canal.agregar(nodo1, peso); } }else{System.out.println(”no hay nodo1”);} }else{System.out.println(”no hay nodo”);} i++; } } iter++; } adyacenciasI.close(); } public void leeCoordenadas() throws IOException { String g = new String(); while ( (g = coordenadasI.readLine()) != null) { if (g.length() != 0) { int i = 0, x = 0, y = 0; String xAux = new String(); String yAux = new String(); char[] aux = g.toCharArray(); while (i ¡g.length() && Character.isDigit(aux[i])) { xAux = xAux + aux[i]; i++; } x = Integer.parseInt(xAux); i++; while (i ¡g.length() && Character.isDigit(aux[i])) { yAux = yAux + aux[i]; i++; } y = Integer.parseInt(yAux); this.lista.agregar(x, y); 44 CAPÍTULO 4. MANUAL TÉCNICO } } coordenadasI.close(); lista.imprime(); } } 4.3.12. Clase ManejoDeArchivosSalida package simulador.negocios; import java.util.*; import java.io.*; import simulador.elementos.*; public class ManejoDeArchivosSalida { DataOutputStream CanalOut; DataOutputStream coordenadasOut; DataOutputStream archivoOut; public ManejoDeArchivosSalida(String path1, String path2, String archivo) throws IOException { CanalOut = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path1))); coordenadasOut = textbfnewDataOutputStream(newBufferedOutputStream(new FileOutputStream(path2))); archivoOut = new DataOutputStream(newBufferedOutputStream(new FileOutputStream(archivo))); this.CanalOut.flush(); } public void archivoDeSalida(cNNodos aux, int num) throws IOException, EOFException { if (aux == null) { CanalOut.close(); coordenadasOut.close(); return; } int i = num; if (aux.size() == 0) { CanalOut.close(); coordenadasOut.close(); return; } for (int j = 0; j ¡aux.size(); j++) { 45 CAPÍTULO 4. MANUAL TÉCNICO cNodo nodo = (cNodo) aux.get(j); while (nodo.getID() != i++) { CanalOut.writeBytes(”n”); coordenadasOut.writeBytes(”n”); } escribeCanal(nodo.getCanal()); escribeCoordenadas(nodo); CanalOut.writeBytes(”n”); coordenadasOut.writeBytes(”n”); } CanalOut.close(); coordenadasOut.close(); return; } public void escribeCanal(cNCanal lista) throwsIOException { if (lista == null) { return; } for (int i = 0; i ¡lista.size(); i++) { CanalOut.writeBytes( ( (cCanal) lista.get(i)).getDestino().getID() + ”,0 ”); } } public void escribeCoordenadas(cNodo lista) throwsIOException { if (lista == null) { return; } coordenadasOut.writeBytes(lista.getX() + ”,”+ lista.getY()); } } faltan unas diagonales en las n’s de las lineas 70, 71, 65 y 66 46