Descripción Funcional y Problemas.

Aplicación Java

    La interfaz de usuario del programa se aprecia en la Figura siguiente:


   El panel rosado corresponde al de Figuras, en que se escoge la forma geométrica que se desea dibujar. El panel celeste contiene las Acciones, que se efectúan sobre las figuras que han sido dibujadas en el panel de Dibujo. En la barra de menú se dispone de dos menús desplegables, Archivo y Edición. En el primero se dan opciones para Almacenar y Cargar archivos, además del comando Salir para cerrar el programa. En el segundo menú solo se da la opción para Borrar las figuras. En los casos de Salir, Cargar o Borrar, el usuario es inquirido sobre si desea almacenar los cambios o desecharlos.

    A continuación se adjuntan las instrucciones para utilizar la aplicación.

* Para crear Circulos:
1.- Primer click con botón izq define el punto de inicio.
2.- El movimiento del mouse define el diámetro.
3.- Click con botón derecho para terminar figura.
* Para crear Rectangulos:
1.- Primer click con botón izq define el punto de inicio.
2.- El movimiento del mouse define alto y ancho.
3.- Click con botón derecho para terminar figura.
* Para crear Polylines:
1.- Primer click con botón izq define el punto de inicio.
2.- El movimiento del mouse define el largo de la línea actual
3.- Doble Click con boton izq. (lo usual) genera una nueva línea 
junto al punto final de la anterior.
4.- El movimiento del mouse define el largo de esta nueva línea. 
Repetir 3.- y 4.- para hacer más líneas.
5.- Click con botón derecho para terminar figura.

* Para las acciones se siguieron los lineamientos de la tarea:
* Para Rotar:
1.- Primer click define punto alrededor del cual se rotará.
2.- Segundo click y manteniendo apretado define el ángulo de rotación.
* Para Trasladar:
1.- Click y arrastre para mover la figura.
* Para Escalar.
1.- Primer click define punto inicial.
2.- Segundo click y arrastre define la distancia hacia el punto inicial.
3.- La distancia define el escalamiento.

 

 Administración de Archivos

    A partir de la clase JFileChooser se ha generado una interfaz de usuario que permite cargar o almacenar archivos. Para darle una mejor funcionalidad a la aplicación, se ha provisto de un filtrado selectivo, lo que permite visualizar solo los archivos .eda o “Todos los archivos”. Para almacenar un archivo basta con proveer su nombre, ya que el programa automáticamente agrega las extensiones .eda y .fig para los respectivos archivos. Para cargar un archivo debe escogerse del listado en el directorio que se encuentre, sin borrar la extensión. Si se introduce sin extensión , se arroja una excepción tipo FileNotFoundException.

 

Problemas

   Los principales problemas estuvieron relacionados con la implementación de transformaciones y la serialización de las instancias de las Figuras.

1.- El manejo de AffineTransforms es especialmente delicado, ya que la transformación afecta todo el espacio de usuario al mismo tiempo. En esta versión del programa se realizaron cambios importantes (ver más abajo) que permitieron prescindir de las AffineTransforms de traslación y escalamiento. La transformación de rotación afecta todo el espacio de usuario, por lo que ha veces se pueden producir efectos extraños en las Figuras. Se intentaron varias formas para evitar esto.

   Una de ellas era la de usar el método createTransformedShape() para crear figuras modificadas por la transformación. Sin embargo, este método afectaba también el espacio de usuario y las coordenadas se veían igualmente afectadas. Se pensaba que el método crearía figuras modificadas tipo Shape, pero al parecer repetía un procedimiento muy similar al de la  AffineTransforms.

   Otra opción, que no se ha alcanzado a implementar aún, consiste en crear una transformación de rotación pero no aplicarla al componente gráfico, sino obtener los coeficientes de la matriz de transformación y aplicarlos manualmente sobre los puntos de las figuras, mediante un método asociado a cada clase. Se cree que esta sería la forma de conseguir reflejar en los datos la rotación y tener control total sobre las figuras.

2.- El cálculo del ángulo fue bastante difícil. Se echo de menos una clase en Java que permitiera un manejo más cómodo de la rotación angular de los objetos. Uno de los principales problemas es que al rotar un rectángulo este deja de ser un rectángulo desde el punto de vista del programa, por lo que su manejo debe realizarse de otra forma. Al final se escogió un método de rotación que aún no está del todo depurado, pero que funciona relativamente bien. El procedimiento comprende armar un triangulo rectángulo, cuya hipotenusa es la distancia desde el punto actual de arrastre hasta el punto de anclaje y un cateto es la distancia desde este punto actual a una recta que une imaginariamente el punto de anclaje con el primer punto de arrastre que se efectuó. De esta manera mediante el arcsen de la razón entre el cateto y la hipotenusa se obtiene el ángulo.

3.- En un principio, se había implementado un borde en el DrawingPanel con el método setBorder(). Sin embargo, al realizar una transformación el borde también era transformado! Al parecer esto es un bug de Java, según se leyó en su sitio web, ya que por error se toma el borde como si perteneciera gráficamente al panel, cuando técnicamente está fuera de él. Se resolvió el problema quitando el borde y prácticamente no se nota.

4.- La serialización provoca bastantes dolores de cabeza, ya que debe ser posible guardar los objetos de tal forma que se puedan leer apropiadamente después. El enfoque de la solución se puede apreciar en la sección de Descripción Operacional, en que se explica el formato de almacenamiento de archivos.

 

Modificaciones respecto a la versión anterior

   Gracias a la necesidad de serializar, se tuvo que hacer una profunda modificación de la estructura del código y la interacción entre clases. A continuación se listan los cambios más relevantes:

·        El hecho de serializar implicó crear clases propias para generar las figuras. De este modo se podían definir apropiadamente los métodos privados readObject y writeObject que implementasen el almacenamiento y lectura de los objetos hacia/desde archivos.

·        Las clases de figuras ( MyLine, MyCirc, MyRect ) implementan ahora sus propios métodos para trasladar y escalar las figuras, modificando los datos y no solo la visión de estos. Con esto, es posible reflejar los cambios en la xfig ya que son los datos los que han sido manipulados. El método de rotar sigue siendo realizado con una AffineTransform. Es bastante elocuente el nuevo diagrama de clases, donde se aprecia una interacción mucho mayor entre ellas en comparación a las versiones anteriores del programa.

·        Se intentó usar la menor cantidad de métodos y variables estáticas para acercarse más a soluciones de tipo orientadas a objeto. La única variable estática de relevancia es el ArrayList figuras, ya que debe ser accesado desde las clases de figuras cuando se invocan sus métodos readObject() para poder almacenar en dicho arreglo las figuras recién leídas.

·        Se implementó un sistema de inicialización para el panel de dibujo. Esto surgió como una necesidad al cargar nuevos archivos, pero fue utilizado para implementar el borrado de figuras desde el panel de dibujo.

 

 

Inicio