Introducción

Andami facilita la creación y gestión de ventanas, ofreciendo una interfaz de ventana que se abstrae de los diferentes tipos de ventanas de Java Swing. De esta forma, cuando queramos crear una ventana, en vez de pensar en ventanas de Swing, simplemente crearemos un panel que implemente la interfaz IWindow y le pediremos a Andami que cree una ventana con las propiedades que deseemos. En función de las propiedades pedidas y el skin instalado, se creará un tipo de ventana distinto (JInternalFrame, JDialog, etc), pero esto será indiferente para nosotros. Para no confundir la ventana real (creada por Andami) con el contenido (creado por nosotros y que implementa la interfaz IWindow), de ahora en adelante usaremos los términos frame , marco o ventana real para referirnos a la ventana creada por Andami, y ventana para referirnos al contenido (que implementa IWindow).

Cuando hablamos de ventanas de Andami, podemos hacer una primera distinción entre ellas: ventana principal, y resto de ventanas. La ventana principal (MainFrame) es la que contiene las barras de herramientas, la barra de estado y (en algunas plataformas) la barra de menús. Esta ventana no está bajo control del gestor de ventanas, sino que se accede a ella usando un método específico de la clase PluginServices. El resto de ventanas sí están bajo el control del gestor de ventanas (MDIManager), al cual debemos dirigirnos para crearlas, cerrarlas o cambiar sus propiedades.

Diagrama de las principales clases implicadas en la gestión de ventanas

Diagrama de las principales clases implicadas en la gestión de ventanas

La ventana principal

MainFrame

La interfaz MainFrame representa la ventana principal de gvSIG, la ventana a la que se añaden los menús, la barras de herramientas, etc. La clase que la implementa (MDIFrame) hereda de JFrame, e incluye el JDesktopPane que se usa para contener las ventanas internas (vistas, mapas, etc). Normalmente, Andami crea automáticamente la interfaz de usuario partiendo de los ficheros config.xml de los plugins. No obstante, MainFrame contiene algunos métodos para modificar por código algunas partes de la interfaz.

La barra de estado: NewStatusBar

La barra de estado es la banda que se muestra en la parte inferior de la ventana principal, y que contiene etiquetas y algunos controles. Es posible cambiar el texto de las etiquetas existentes, así como añadir otras etiquetas o controles.

Cambia el texto mostrado en la etiqueta id por nuevoTexto. id se debe corresponder con el atributo id de una etiqueta definida en el config.xml o si se trata de un control, con el nombre del control.

Muestra un mensaje de información en la parte izquierda de la barra de estado, siempre que actualmente no se esté mostrando un mensaje temporal. Si se está mostrando un mensaje temporal, el mensaje establecido ahora se mostrará cuando se llame al método restaurarTexto().

Muestra un mensaje de aviso en la parte izquierda de la barra de estado, siempre que actualmente no se esté mostrando un mensaje temporal. Si se está mostrando un mensaje temporal, el mensaje establecido ahora se mostrará cuando se llame al método restaurarTexto().

Muestra un mensaje de error en la parte izquierda de la barra de estado, siempre que actualmente no se esté mostrando un mensaje temporal. Si se está mostrando un mensaje temporal, el mensaje establecido ahora se mostrará cuando se llame al método restaurarTexto().

Detalle de mensajes de información, aviso y error en la barra de estado

Detalle de mensajes de información, aviso y error en la barra de estado

Muestran un mensaje de información, aviso u error (respectivamente), pero sólo de forma temporal, ya que si a continuación usamos el método restaurarTexto() se vuelve a mostrar el mensaje anterior.

Si progress está entre 0 y 99 (inclusive), muestra una barra de progreso en la parte izquierda y avanza la posición a ese valor. Si progress es mayor o igual que 100, oculta la barra de progreso.

Detalle de la barra de progreso

Detalle de la barra de progreso

Skins de Andami (libCorePlugin)

Mientras la gestión de plugins se incorpora directamente en Andami, la gestión de ventanas se delega en los llamados skins de Andami. Andami ofrece unas interfaces y objetos para la gestión de ventanas: IWindow, MDIManager, WindowInfo, IWindowListener, SingletonWindow... dichas interfaces deben ser implementadas por el skin, quien realmente realizará la gestión de ventanas. De esta forma, se podría llevar a cabo una gestión de ventanas distinta, implementando un skin distinto. Actualmente sólo existe un Skin implementado, llamado CorePlugin. Formalmente, es un plugin más de Andami, pero con la particularidad de que Andami no arrancará si CorePlugin (u otro skin) no está instalado. Los skins deben incluir una extensión especial, que implemente IExtension y MDIManager, y que se define en el config.xml con la etiqueta skin-extension.

Clases principales de CorePlugin y clases relacionadas de Andami.

Clases principales de CorePlugin y clases relacionadas de Andami


Gestión de ventanas

La interfaz IWindow

Cualquier ventana que deseemos crear a través de Andami debe implementar la interfaz IWindow. Conviene aclarar que IWindow no será una ventana de Swing, sino el contenido de la ventana (normalmente una clase que herede de JPanel a la que añadiremos todos los componentes necesarios). La ventana propiamente dicha (frame), será creada por Andami y no tendremos acceso directo a ella.

La interfaz IWindow sólo posee un método, que especifica las propiedades iniciales que deberá tener la ventana creada (posición, tamaño, tipo, título, etc.):

public WindowInfo getWindowInfo()

Este método será usado por Andami en el momento de la creación de la ventana real para determinar las propiedades y el tipo de ventana a crear. El objeto devuelto por este método es de tipo WindowInfo, el cual describe las propiedades de una ventana de Andami (explicado en la sección siguiente). Debemos hacer hincapié en que este método sólo devuelve las propiedades iniciales y que por tanto no debemos usar este método para obtener o modificar las propiedades de la ventana, para esta tarea nos dirigiremos al gestor de ventanas.

La mayoría de las ventanas que creemos no implementarán directamente IWindow, sino una interfaz más específica, SingletonWindow, que asocia un modelo a cada ventana. Este modelo se utiliza para dotar de identidad a las ventanas, de forma que al intentar crear una ventana con un modelo que ya esté asociado a otra ventana, obtendremos una referencia a esta segunda ventana.

Propiedades de ventana: WindowInfo

El objeto WindowInfo almacena las propiedades de una ventana de Andami, de forma que existe un objeto WindowInfo asociado a cada ventana (IWindow) creada por Andami. Puede usarse tanto para consultar las propiedades actuales de la ventana como para modificarlas. Al modificar una propiedad de WindowInfo, este ventana se refleja inmediatamente en la ventana asociada.

Atendiendo el comportamiento que tendrá la ventana respecto a las otras, existen ventanas de tres tipos: normales, modales y modeless.

Debemos tener en cuenta que las ventanas modeless sólo lo serán respecto a las ventanas normales; es decir, una ventana modeless siempre estará encima de las ventanas normales existentes, pero podrá estar encima o debajo de otra ventana modeless, dependiendo de qué ventana seleccionemos.

De forma similar, las ventanas modales sólo lo serán respecto a las ventanas normales o modeless; es decir, siempre estarán encima de las ventanas normales o modeless existentes, pero podrán estar encima o debajo de otras ventanas modales, dependiendo de qué ventana esté seleccionada.

El tipo de ventana que se creará a partir de un objeto WindowInfo depende de las propiedades suministradas al constructor del objeto. Por ejemplo, para crear una ventana modal, el método getWindowInfo() de la ventana deberá contener el siguiente código:

WindowInfo windowInfo = new WindowInfo(WindowInfo.MODALDIALOG);
return windowInfo;

Para crear una ventana modeless:

WindowInfo windowInfo = new WindowInfo(WindowInfo.MODELESSDIALOG);
return windowInfo;

Para crear una ventana normal:

WindowInfo windowInfo = new WindowInfo();
return windowInfo;

Existen otras propiedades que podemos especificar en el constructor, que añadiremos usando el operador de suma binaria |:

Para crear una ventana modeless redimensionable y maximizable:

WindowInfo windowInfo = new WindowInfo(WindowInfo.MODELESSDIALOG | WindowInfo.RESIZABLE | WindowInfo.MAXIMIZABLE);
return windowInfo;

No es posible utilizar simultáneamente las propiedades MODELESSDIALOG y MODALDIALOG. Además de que no tiene sentido, si lo hacemos obtendremos un error de Andami.

Hasta aquí hemos visto las propiedades que acepta el constructor de la clase WindowInfo, y que determinan el comportamiento de la ventana. Además de esto, existe una serie de métodos que permiten consultar diversas propiedades de la ventana, así como modificarlas:

Devuelve la coordenada X (en píxeles) del vértice superior izquierdo de la ventana. El origen de coordenadas (punto 0, 0) se sitúa en la parte superior izquierda de la ventana principal, justo debajo de la barra de herramientas.

Establece la coordenada X (en píxeles) del vértice superior izquierdo de la ventana.

Devuelve la coordenada Y (en píxeles) del vértice superior izquierdo de la ventana. El origen de coordenadas (punto 0, 0) se sitúa en la parte superior izquierda de la ventana principal, justo debajo de la barra de herramientas.

Establece la coordenada Y (en píxeles) del vértice superior izquierdo de la ventana.

Cuando la ventana no está maximizada, obtiene la coordenada X (en píxeles) del vértice superior izquierdo. Cuando está maximizada, devuelve la coordenada X que tendría la ventana si no estuviese maximizada.

Establece la coordenada X (en píxeles) del vértice superior izquierdo de la ventana cuando la ventana está no-maximizada. Si la ventana está maximizada actualmente, este método no cambia su estado, pero al restaurar la ventana al estado normal la coordenada X será la establecida aquí.

Cuando la ventana no está maximizada, obtiene la coordenada Y (en píxeles) del vértice superior izquierdo. Cuando está maximizada, devuelve la coordenada Y que tendría la ventana si no estuviese maximizada.

Establece la coordenada y (en píxeles) del vértice superior izquierdo de la ventana cuando la ventana está no-maximizada. Si la ventana está maximizada actualmente, este método no cambia su estado, pero al restaurar la ventana al estado normal la coordenada X será la establecida aquí.

Devuelve la anchura (en píxeles) de la ventana.

Establece la anchura (en píxeles) de la ventana.

Devuelve la altura (en píxeles) de la ventana.

Establece la altura (en píxeles) de la ventana.

Cuando la ventana no está maximizada, obtiene la anchura (en píxeles) de la ventana. Cuando está maximizada, devuelve la anchura que tendría la ventana si no estuviese maximizada.

Establece la anchura (en píxeles) de la ventana cuando no está minimizada. Si la ventana está maximizada actualmente, este método no cambia su estado, pero al restaurarla al estado normal la ventana tendrá la anchura establecida aquí.

Cuando la ventana no está maximizada, obtiene la altura (en píxeles) de la ventana. Cuando está maximizada, devuelve la altura que tendría la ventana si no estuviese maximizada.

Establece la altura (en píxeles) de la ventana cuando no está minimizada. Si la ventana está maximizada actualmente, este método no cambia su estado, pero al restaurarla al estado normal la ventana tendrá la altura establecida aquí.

Obtiene la posición y dimensiones (en píxeles) de la ventana.

Establece la posición y dimensiones (en píxeles) de la ventana.

Cuando la ventana no está maximizada, obtiene la posición y dimensiones (en píxeles) de la ventana. Cuando está maximizada, devuelve la posición y dimensiones que tendría la ventana si no estuviese maximizada.

Establece la posición y dimensiones (en píxeles) de la ventana cuando está no-maximizada. Si la ventana está maximizada actualmente, este método no cambia su estado, pero al restaurarla al estado normal la ventana tendrá la posición y dimensiones establecidas aquí.

Obtiene el actionCommand la herramienta seleccionada asociada a la ventana actual (ver la descripción de <selectable-tool> para conocer el mecanismo de herramientas seleccionables).

Obtiene el título de la ventana.

Establece el título de la ventana.

Obtiene el identificador de ventana.

Establece el identificador de ventana.

Devuelve cierto (true) si la ventana está cerrada, falso (false) en caso contrario.

Establece si la ventana está abierta o cerrada. La ejecución de este método no cambia el estado de la ventana, use PluginServices.getMDIManager().addWindow(window) y PluginServices.getMDIManager().closeWindow(window) para abrir o cerrar una ventana.

Devuelve cierto (true) si la ventana es minimizable, falso (false) en caso contrario.

Devuelve cierto (true) si la ventana es maximizable, falso (false) en caso contrario.

Establece si la ventana es maximizable o no. La ejecución de este método no cambia el estado de la ventana una vez se ha creado, se debe definir si la ventana es maximizable antes de crearla.

Devuelve cierto (true) si la ventana está maximizada, falso (false) en caso contrario.

Maximiza o restaura la ventana dependiendo del parámetro maximized.

Devuelve cierto (true) si la ventana es modal, falso (false) en caso contrario.

Devuelve cierto (true) si la ventana es modeles, falso (false) en caso contrario.

Devuelve cierto (true) si la ventana está actualmente en modo paleta (flotante), falso (false) si está empotrada en la ventana correspondiente.

Establece si la ventana está en modo paleta o no. La ejecución de este método no cambia el estado de la ventana, simplemente actualiza el objeto WindowInfo. Use la interfaz IWindowTransform para pasar una ventana a modo paleta o restaurarla a modo empotrado.

Devuelve cierto (true) si la ventana es redimensionable, falso (false) en caso contrario.

Devuelve cierto (true) si la ventana es visible, falso (false) en caso contrario.

El tamaño, la posición y el estado de las ventanas se almacena en los proyectos de gvSIG, esta información se usa al abrir un proyecto para restaurar las ventanas a su estado anterior. Es posible que no deseemos que se almacene el estado de una ventana concreta (por ejemplo, porque inicialmente deba estar siempre cerrada o en una posición exacta). Este método establece si el estado de esta ventana debe guardarse en los proyectos de gvSIG o debe ser ignorada.

Devuelve cierto (true) si el estado de esta ventana debe guardarse en los proyectos de gvSIG, falso (false) si debe ser ignorada.

Obtiene un árbol XML que almacena las propiedades de este objeto WindowInfo. Es útil para salvar las propiedades de la ventana.

public static WindowInfo createFromXMLEntity(XMLEntity xml)

Método estático que crea un objeto WindowInfo a partir de las propiedades almacenadas en el árbol XML suministrado.

El gestor de ventanas: MDIManager

La interfaz MDIManager nos permite interactuar con las ventanas. Es el punto al que debemos dirigirnos para crear ventanas, cerrarlas, cambiarles el tamaño, obtener la ventana activa, obtener la lista de todas las ventanas, etc. Durante la creación de ventanas, se encarga de crear las ventanas con unas propiedades homogéneas (teniendo en cuenta, eso sí, las propiedades que hemos solicitado) y registrarlas en el menú Ventana, entre otras cosas. También se encarga de escuchar los cambios producidos en los objetos WindowInfo para reflejar estos cambios en la ventana real asociada.

Como ya se ha comentado, la gestión de ventanas de Andami es bastante particular porque el programador sólo debe crear un panel con el contenido de la ventana, y MDIManager creará la ventana real. Por esta razón, para cambiar las propiedades de una ventana debemos dirigirnos a MDIManager, que es quien conoce la implementación real de la ventana (frame).

Diagrama que muestra las principales clases relacionadas con el gestor de ventanas

Diagrama que muestra las principales clases relacionadas con el gestor de ventanas

MDIManager posee un amplio rango de métodos para interactuar con las ventanas. La mayoría de ellos requieren una referencia al objeto IWindow que deseamos alterar. Otros, por contra, devuelven una referencia a tal objeto.

Métodos para crear ventanas

Crea un nuevo frame cuyo contenido será panel. Las propiedades iniciales de la ventana creada (tamaño, tipo, etc), vendrán determinadas por el método getWindowInfo() de panel. Si la ventana es de tipo MODAL, se creará en posición centrada, ignorando la posición especificada en getWindowInfo. Si la ventana es de tipo SingletonWindow y ya existe una ventana con el mismo modelo, no se creará una ventana nueva sino que la ventana ya existente se traerá a primer plano y se le dará el foco. En este caso se devolverá una referencia a dicha ventana ya existente.

Método idéntico a addWindow, salvo que crea todas las ventanas en posición centrada, ignorando la posición especificada por el método getWindowInfo() de panel.

Métodos para cerrar ventanas

Cierra todas las ventanas abiertas.

Cierra la ventana window.

Cierra la ventana Singleton que tenga como modelo el objeto model.

Cierra la ventana Singleton cuya clase y modelo se pasan como parámetros.

Métodos para obtener las ventans existentes

Obtiene un vector que contiene todas las ventanas que están abiertas actualmente, incluyendo las minimizadas y maximizadas. La ventana principal no está incluída, ya que no está bajo el control de MDIManager.

Obtiene un vector que contiene todas las ventanas que están abiertas actualmente, ordenado según la profundidad (posición Z) de las ventanas. Es decir, la primera ventana del vector será la ventana que esté en primer plano (delante de las demás) y la última ventana del vector será la que esté más al fondo (detrás de las demás).

Devuelve la ventana activa en este momento, excluyendo las ventanas modales y las ventanas tipo PALETTE. Si la ventana activa actual es modal o tipo PALETE, devuelve la última ventana activa que no fuese modal ni tipo PALETTE. Esto es así porque se considera que las ventanas modales y tipo PALETTE no están al mismo nivel que las demás, sino que son ventanas auxiliares (normalmente contienen algún tipo de herramienta para manipular el contenido de otra ventana o presentan alguna información puntual).

Devuelve la ventana que posee el foco en este momento, excluyendo las ventanas modales. Si la ventana que posee el foco actualmente es modal, devuelve la última ventana no-modal que tuvo el foco.

Métodos para modificar propiedades de ventanas

Obtiene el objeto WindowInfo asociado a la ventana window. Este objeto contiene información actualizada sobre la posición, tamaño, título, etc. Además de proporcionar información, este objeto puede utilizarse para hacer cambios en las propiedades de la ventana (tamaño, posición, etc). En Propiedades de ventana: WindowInfo se describe en detalle las propiedades que se pueden modificar usando este objeto.

Centra la ventana panel.

Actualiza las propiedades de la ventana window usando los valores especificados en el objeto wi.

Normalmente, las ventanas se redibujan automáticamente cuando corresponde, de acuerdo al layout asignado y a los cambios de tamaño, etc. Sin embargo, si queremos forzar un redibujado, podemos hacerlo usando este método.

Otros métodos de utilidad

Muestra el icono de espera como cursor del ratón, y bloquea todos los eventos que se produzcan en la ventana principal hasta que se reciba una llamada a restoreCursor().

Restaura el icono de ratón que hubiese antes de comenzar la operación, y reactiva el manejo de eventos de la ventana principal.

Establece la imagen proporcionada como fondo de la ventana principal. El argumento typeDesktop debe tomar uno de los siguientes valores: Theme.CENTERED, Theme.EXPAND, Theme.MOSAIC (para indicar que la imagen debe situarse bien centrada, bien debe expandirse para ocupar todo el tamaño de la ventana, o bien debe repetirse formando un mosaico hasta llenar todo el espacio).

La interfaz SingletonWindow

Existe un tipo de especial de ventanas de Andami: las ventanas Singleton, ventanas que tienen asociado un modelo. El modelo puede ser cualquier objeto Java que elijamos, y nos sirve para dotar de identidad a la ventana. De esta forma, existirá una única ventana asociada a un modelo, y podremos hacer referencia a la ventana a través del modelo. Si intentamos añadir una ventana Singleton cuyo modelo ya está asociado a otra ventana existente, en vez de crearse una nueva ventana se mandará la ventana existente a primer plano, y obtendremos una referencia a dicha ventana.

La interfaz Singleton cuenta simplemente de un método:

public Object getWindowModel()

Devuelve el modelo de esta ventana Singleton. El modelo debería ser constante en el tiempo para una ventana dada, salvo que realmente queramos cambiar la identidad de la ventana.

La interfaz SingletonWindow extiende la interfaz IWindow, por lo que cualquier ventana que implemente SingletonWindow implementará también IWindow.

La interfaz IWindowListener

La interfaz IWindowListener permite a las ventanas que la implementen registrarse como listener (oyente) de los eventos que suceden sobre sí mismas.

public void windowActivated()

Este método se ejecutará cada vez que se active la ventana.

public void windowClosed()

Este método se ejecutará cuando la ventana se esté cerrando.

Para recibir estos eventos, basta con que las ventanas implementen esta interfaz, Andami lo detectará y les enviará los eventos correspondientes sin necesidad de seguir ningún paso adicional.

La interfaz IWindowTransform

Las ventanas tipo PALETTE (ventanas que pueden empotrarse dentro de otras o bien estar en modo flotante o paleta) deben implementar esta interfaz, para pasar correctamente de modo paleta a modo empotrado.

Esta interfaz posee tres métodos, que la ventana debe implementar correctamente de acuerdo a su contexto (ya que cada herramienta adoptará una forma particular en modo empotrado y en modo flotante):

public void toPalette()

Pide a la ventana que se transforme en modo flotante.

public void restore()

Pide a la ventana que se transforme en modo empotrado.

isPalette()

Devuelve cierto si la ventana está en modo paleta (flotante), falso si está en modo empotrado.

Cached time 11/22/13 06:39:11 Clear cache and reload