Diseño y Programación Orientados a Objetos
1er. Sem 2017
Tarea 2: Simulación Gráfica de Ascensor

Lea detenidamente la tarea. Si algo no lo entiende, consulte en clases. Si es preciso, se incorporarán aclaraciones al final.
Objetivos de la tarea:
* Manejar proyectos vía GIT.
* Crear Interfaces gráficas en Java.
* Manejar eventos de software.
* Ejercitar la creación y extensión de clases para satisfacer nuevos requerimientos.
* Ejercitar creación y uso de excepciones en Java.
* Ejercitar el patrón de diseño "Modelo-Vista-Controlador".
* Generar documentación usando Javadoc.

Descripción General

  En esta tarea se pide crear una interfaz gráfica para el ascensor definido en la Tarea 1. La interfaz gráfica de su solución Los ascensores normalmente tienen: botonera en cada piso para solicitar ascensor, botonera dentro del ascensor (cabina) para indicar destino, la cabina misma con su motor, sensores de llegada de la cabina a cada piso, y una unidad de control con la lógica requerida para accionar la detención, subida y bajada de la cabina, además de apagar las luces de solicitud en botoneras, ver figura 1.



Figura 1: Esquema simple de la interfaz gráfica esperada para un ascensor para cuatro pisos
Todos conocemos y hemos usado un ascensor alguna vez, por lo cual descripciones detalladas de todo no son necesarias. Cuando hay varios adyacentes, todos trabajan en conjunto. En esta tarea consideraremos un sólo ascensor. La solución a programar en esta tarea es simple; sin embargo, debe reflejar la operación de ascensores reales. Las botoneras poseen una luz integrada a cada botón.
(1) Así al "llamar" a un ascensor en una dirección (para subir o bajar desde un piso), se enciende el botón. Cuando el ascensor llega al piso en la dirección solicitada, se apaga el botón y se detendrá por al menos dos segundos.
(2) Al seleccionar un piso destino dentro de la cabina, se encenderá el botón asociado a ese piso. Cuando la cabina llega al piso, la luz de ese piso se apaga.
El modelo de la Figura 1 ayuda a identificar los elementos visibles de su interfaz gráfica. Para simplificar la tarea, la interfaz gráfica no mostrará el motor y cables que hacen subir y bajar la cabina ni la unidad de control.
1 y 2 describen someramente dos casos de uso del sistema.
Basado en su solución de la tarea 1 o en el código de ayuda inicial para esta tarea, usted debe crear clases para definir vistas para: cabina, botonera de cabina, caja del ascensor, sensores, y botoneras de piso.
Su programa vinculará objetos de distintas clases de manera de simular el comportamiento del ascensor ante los eventos generados en las botoneras de un edificio de 5 pisos.

Desarrollo en Etapas

Para llegar al resultado final de esta tarea usted aplicará la metodología "Iterativa e Incremental" para el desarrollo de software. Su grupo irá desarrollando etapas que irán abordando los requerimientos gradualmente. En cada etapa usted obtendrá una solución que funciona para un subconjunto de los requerimientos finales. Su grupo deberá entregar una solución para cada una de las etapas aún cuando la última integre las primeras. Esto tiene por finalidad, educar en la metodología iterativa e incremental.

Primera Etapa

Esta etapa sólo se implementa clases para representar la vista de la botonera de cada piso. A partir de su solución para la tarea 1, el programa procesará los llamados de cada piso efectuados al presionar los botones de piso (5 pisos). El paso del ascensor por cada piso se debe reflejar cambiando el indicador de ubicación del ascensor. Cuando la cabina -que no veremos en esta etapa- llegue al piso del llamado, se debe apagar la luz de la botonera que corresponda. La vista del programa para esta etapa corresponde a la zona derecha de la figura 1, pero de 5 pisos en lugar de 4. En esta etapa sólo se actuará sobre las botoneras de piso y el ascensor debe responder como la etapa 4 de la tarea 1. Usted puede revisar y usar una solución muy cercana a lo pedido en la etapa 4 (su diagrama de clases) de la tarea 1 que usted puede usar como base, además de las clases de ayuda para esta etapa (diagrama de clases de esta idea -incluyendo archivos de la solución de T1- ).

Segunda Etapa

En esta segunda etapa se incluirá las vistas de la Caja del Ascensor, la Cabina y los Sensores. La zona central de la figura 1 se agrega a la zona derecha. Ahora será posible observar el movimiento de la cabina en la caja del ascensor y el encendido de los sensores cuando la cabina pasa por o llega a cada uno de los 5 pisos. Su grupo generará un programa de prueba stage2Test.java el cual permitirá llamar la cabina desde cualquier piso. Como en la tarea 1, al llegar a un piso solicitado, se apaga la luz del botón llamador que correspona y se detiene brevemente la cabina. Usted puede  el siguiente código como base para esta etapa. Cabe destacar que si bien se acepta el uso de sleep para detener la cabina, esta técnica tiene como efecto lateral el que puede dejar la interfaz sin respuesta mientras se efectúa la espera. Por esto Swing podría no refrescar la pantalla sino hasta el final de la pausa y podría no responder inmediatamente a los eventos del mouse mientras se está en "sleep". Aquí puede ver video del ascensor usando sleep, acá sin usar sleep (esta verión generó el sleep usando contador decreciente decrementado en actionPerformed, no se pide para su tarea)

Tercera Etapa

Como tercer paso su grupo debe incorporar la vista de la botonera de cabina. Así su interfaz gráfica se verá como la figura 1 con la omisión de la barra de menú. Para separar la vista de la botonera de cabina (vista interna de la cabina) de los otros objetos gráficos del edificio use un JSplitPane. La botonera de la cabina debe permitir acceder a cualquiera de los 5 pisos. 

Cuarta Etapa

En esta etapa usted incorporará una barra que contiene el menú "Configuration". Al seleccionar este menú se muestran dos ítems. El primero es "Speed", el cual muestra una ventana de diálogo para cambiar la rapidez de movimiento de la cabina. La segunda opción es "Pause time", la cual permite cambiar el tiempo de detención del ascensor al tomar o dejar personas. Si el usuario ingresa un dato no válido (un texto o número negativo), el Motor lanzará una excepción cuando se intente cambiar su atributo "speed" o tiempo de pausa a un valor no válido. En este caso el listener asociado a la opción del menú debe solicitar nuevamente el ingreso del parámetro.

Resultados Esperados de su Grupo

Usted deberá documentar, usando notación "JavaDoc" las clases BotoneraCabina y BotoneraCabinaView de su última etapa.
Prepara un archivo makefile para compilar y ejecutar su tarea en aragorn. Además incluya rótulos "clean" para borrar todos los .class generados, y "doc" para generar la documentación en directorio "documentation".
Entregue todo lo indicado en Normas de Entrega de Tareas. Su documentación automática con javadoc debe ser generable con:
$ make doc
Para que esto funcione usted debe incluir el rótulo doc en su archivo makefile.
(OJO no incluya las páginas html generadas por javadoc, éstas serán generadas por este comando cuando el ayudante las revise)
En su archivo de documentación (pdf o html) incorpore el diagrama de clases de la aplicación. Éste lo puede generar con jgrasp u otro programa.

Extra créditos

Su grupo puede aspirar a 5 puntos adicionales (la nota igualmente se satura en 100%) si agrega una luz para la cabina de manera que esté encendida cuando suponemos alguien se encuentra en su interior. Esta luz se enciende al llegar al piso del primer llamado (luego de tener el ascensor detenido) y se apaga luego de 5 segundos sin recibir nuevas solicitudes después de haber satisfecho la última solicitud. La luz se hace notar porque la cabina cambiará de color cuando ésta está encendida; por ejemplo, fondo gris pasa a blanco. En archivo Readme indique si abordó este requerimiento.

Ayudas
* Revise las instrucciones para la realización de tareas.
* Dé una mirada a los códigos de avance proporcionados. Si encuentra errores o algo mejorable, avise al profesor.
* No dude en consultar al profesor o ayudantes sobre dudas de esta tarea.

Sobre la arquitectura Modelo Vista Controlador
Para organizar interfaces gráficas una "solución de software general recomendada" (éstas son conocidas como patrones de diseño) es el "modelo-vista-controlador". El modelo es la clase que caracteriza a un objeto y almacena los datos significativos de éste. En este caso la clase Cabina maneja el modelo de una cabina, también las clases BotoneraPisoIntermedio, Sensor, CajaAscensor manejan el modelo para esas categorías de objetos. Por otro lado tenemos las vistas, estas clases indican cómo un modelo se muestra visualmente. Estas clases representan visualmente los objetos del problema. En nuestro caso Cabina, BotoneraPisoIntermedio, Sensor, y CajaAscensor poseen sus vistas en las clases CabinaView, BotoneraPisoIntermedioView, SensorView, y CajaAscensorView. No es el caso de esta tarea, pero un objeto podría tener varias vistas para sus datos; por ejemplo un objeto termómetro tiene un modelo y podría tener varias formas de mostrarse: como columna de mercurio, como número digital, como un color, etc. Finalmente tenemos el controlador. Las clases controladoras son aquellas que modifican los datos, por ejemplo a través de las acciones del usuario en la interfaz. Generalmente las clases controladoras son los "listeners" o manejadores de los eventos que usted estima de interés. Una clase puede cumplir dos roles, por ejemplo modelo y controlador. Así como podemos tener varias vistas, es posible tener varias clases controladoras de un modelo. Otras clases controladoras son el listener que responde a las opciones de selección del menú y el listener que responde a los eventos del mouse cuando presionamos sobre la botonera.