Extensión para crear fichas sobre el Layout

 

Introducción
ÁRBOL DEL TEMPLATELAYOUT
FICHEROS Y CLASES
    TemplateExtension.java
        Métodos de la interfaz
        inicializar()
        execute(String ActionCommand)
        isEnabled()
        isVisible()
        Métodos propios de la extensión TemplateLayout
        initFFrameText()
        initTemplates(FFrameView fframeview)
        initFFrameText(FFrameText fframetext)
        endFFrameText()
        askAll()
        askOne()
    askOne.java
    askAll.java
    Iver-utilies.jar
    gdbms.jar
    config.xml
    Directorio images
    Directorio lib
    build.xml
    Ficheros *.properties

Introducción

TemplateLayout es un plugin con una única extensión (TemplateExtension.java) y es capaz de crear fichas personalizadas a partir de un tag y una selección en la vista con capas  de formato shape accediendo a sus respectivos fichero dbf y recuperar sus atributos.

El tag, se puede introducir en un FFrame (Forma gráfica que se puede añadir en el layout ) ,de tipo texto (FFrameText).

Por defecto, la extensión no ofrece la posibilidad de añadir un tag en cualquier elemento del layout. Para poder añadir un tag lo que se debe hacer primero es activar desde el diálogo de configuración de ANDAMI la extensión: com.iver.cit.gvsig.TagExtension, y cerrar la aplicación para volverla a ejecutar y que estos cambios surtan efecto en el programa y de esta forma podamos establecer a los FFrameText los tag que tendrán que coincidir con el nombre del campo del valor que queremos mostrar.

Después de activar la extensión TagExtension mencionada, ya podemos añadir un tag y utilizarlo desde cualquier otra extensión.

El código fuente de este plugin, está comentado casi línea a línea.

Descarga del plugin: TemplateLayout

Árbol del TemplateLayout

Clases y ficheros del plugin en forma de árbol. Esta imagen es una captura de pantalla del proyecto TemplateLayout en Eclipse(IDE utilizada por el equipo de desarrollo de gvSIG).

Ficheros y clases

TemplateExtension.java

Esta clase es el centro de la extensión, es en esta clase donde se implementa la interfaz com.iver.andami.plugins.Extension.

Por un lado tenemos los métodos que aporta la interfaz y por otro, los que necesitamos para la tarea que debe hacer nuestra extensión en particular.

Métodos de la interfaz

Métodos que aporta la interfaz Extensión y tienen que implementar todas las extensiones de Andami.

 

Inicializar()

En nuestro caso no hemos implementado nada en este método que es ejecutado al inicializar la extensión.

Execute(String actionCommand)

Método invocado para realizar la acción que se quiera, cuando se selecciona la extensión. En nuestro caso, obtenemos el Layout que contiene la vista actualmente seleccionada en ANDAMI.

                        layout = (Layout) PluginServices.getMDIManager().getActiveView();

 

Obtengo todos los FFrames que contiene el Layout:

                        fframes = layout.getFFrames();

 

Recorro todos los FFrames comprobando si es una instacia de FFrameView para ejecutar initTemplates en el caso de que así sea.

                        for (int i = 0; i < fframes.size(); i++) {

                                   if (fframes.get(i) instanceof FFrameView) {

                                               try {

Inicia la creación de todas las platillas posibles a partir de fframeview.

                                                           initTemplates((FFrameView) fframes.get(i));

                                               } catch (DriverException e) {

                                                           e.printStackTrace();

                                               } catch (com.hardcode.gdbms.engine.data.DriverException e) {

                                                           e.printStackTrace();

                                               } catch (DriverIOException e) {

                                                           e.printStackTrace();

                                               }

                                   }

                        }

isEnabled()

Si este método devuelve true, indicará que el botón o opción de menú que esté vinculada a esta extensión estará habilitada. En TemplateLayout devolvemos un true fijo y así siempre esta en modo habilitado, pero es posible que en cualquier otra extensión se quiera crear una condición para habilitarlo.

 

isVisible()

 

Si devuelve true, el botón o opción de menú, estará visible y si por el contrario devuelve false, se ocultará.

En está extensión si que hemos creado una condición en este método para ponerlo en estado visible cuando queramos.

Obtenemos la vista activada actualmente:

                        View f = PluginServices.getMDIManager().getActiveView();

 

Se comprueba si la vista es null y se devuelve un false para no hacer visible la extensión.

                        if (f == null) {

                                   return false;

                        }

 

Se comprueba si la vista activa contiene un Layout y si es así se devuelve true como visible o false si no contiene un Layout.

                        if (f.getClass() == Layout.class) {

                                   return true;

                        } else {

                                   return false;

                        }

 

Métodos propios de la extensión TemplateLayout

 

Métodos propios de la extensión en la que nos encontramos y que no tienen nada que ver con los métodos proporcionados por la interfaz.

 

initFFrameText()

Este método guarda el contenido de todos los FFrameText para poder  recuperarlos cuando finalice la creación de fichas.

Recorro todos los FFrames que contiene el Layout y compruebo que son una instancia de FFrameText, para guardar en hastext (HashTable) el texto y su FFrameText.

                        for (int ft = 0; ft < fframes.size(); ft++) {

                                   if (fframes.get(ft) instanceof FFrameText) {

                                               ArrayList al = new ArrayList();

                                               for (int i = 0;

                                                                       i < ((FFrameText) fframes.get(ft)).getText().size();

                                                                       i++) {

                                                           al.add(((FFrameText) fframes.get(ft)).getText().get(i));

                                               }

                                               hashtext.put(fframes.get(ft), al);

                                   }

                        }

 

initTemplates(FFrameView fframeview)

Inicia la creación de todas las platillas posibles a partir de un FFrameView.

Inicio la opción de cancelar la impresión de todas las fichas a true.

                        printAll[1] = true;

Rectángulo del extent inicial de la vista contenida en el FFrameView.

                        Rectangle2D.Double rectIni = new Rectangle2D.Double();

                        rectIni.setRect(fframeview.getFMap().getViewPort().getExtent());

Entero que representa el tipo de escala que tiene seleccionada el FFrameView.

                        int typeScaleIni = fframeview.getTypeScale();

Guarda los textos iniciales de todos los FFrameText

                        initFFrameText();

Recorro todas las capas de la vista.

                        for (int i = 0; i < fframeview.getFMap().getLayers().getLayersCount();i++) {

Compruebo que la capa este activada.

                                   if (fframeview.getFMap().getLayers().getLayer(i).isActive()) {

Obtengo su recordSet

                                               If (fframeview.getFMap().getLayers().getLayer(i) instanceof AlphanumericData) {

                                                           SelectableDataSource dataSource = ((AlphanumericData) fframeview.getFMap().getLayers().getLayer(i)).getRecordset();

Recorro todos los registros.

                                                           for (long k = 0; k < dataSource.getRowCount(); k++) {

Compruebo que está seleccionado.

                                                                       if (dataSource.isSelected((int) k)) {

Obtengo el rectángulo del shape para después ponerlo como extent del FFrameView

                                                                                  Rectangle2D rec = ((SingleLayer) fframeview

                                                                                                                                    .getFMap().getLayers().getLayer(i)).getSource() .getShape((int) k).getBounds2D();

Cambio el extent de la vista que contiene fframeview, del que tenía al extent del shape seleccionado.

                                                                                  fframeview.setNewExtent(rec);

 

Cambio el tipo de escala de fframeview a Escala especificada por el usuario.

                                                                                  fframeview.setTypeScale(FFrameView.MANUAL);

 

Recorro todos los FFrames que contiene el Layout y compruebo que son una instancia de FFrameText, para inicializarlo con el valor correspondiente.

                                                                                  for (int ft = 0; ft < fframes.size(); ft++) {

                                                                                              if (fframes.get(ft) instanceof FFrameText) {

                                                                                                          if (fframeview != null) {

initFFrameText((FFrameText) fframes.get(

                                                                                                                                             ft), dataSource, k);

                                                                                                          }

                                                                                              }

                                                                                  }

                                                                                  if (isFirst) {

Si es el primer registro seleccionado se abre el diálogo para preguntar si se quiere imprimir todas las fichas.

                                                                                              askAll();

                                                                                               isFirst = false;

                                                                                  }

                                                                                  if (!printAll[1]) {

Si se cancela la impresión desde el diálogo askAll se termina la creación de fichas.

Pongo isFirst a true para que la próxima vez que se llame a este método se pregunte si se quiere imprimir todas las fichas.

                                                                                              isFirst = true;

                                                                                              return;

                                                                                  }

 

                                                                                  if (printAll[0]) {

Imprime la ficha actual.

                                                                                              printExtension.printLayout(layout);

                                                                                  } else {

Refrescar el Layout para ver la ficha actual en pantalla.

                                                                                              layout.refresh();

                                                                                              layout.refresh();

Preguntar si se quiere imprimir la ficha actual.

                                                                                              askOne();

                                                                                  }

                                                                       }

                                                           }

                                               }

                                   }

                        }

 

Recupera el Extent inicial del FFrameView.

                        fframeview.getFMap().getViewPort().setExtent(rectIni);

Recupera el tipo de escala que tenía seleccionada el FFrameView.

                        fframeview.setTypeScale(typeScaleIni);

Recupera el texto de todos los FFrameText del Layout.

                        endFFrameText();

Refresca el Layout en pantalla.

                        layout.refresh();

Volvemos a inicializar el boolean que sirve para saber si estamos en la primera ficha a imprimir.

                        isFirst = true;

            }

initFFrameText(FFrameText fframetext)

            Modifica el FFrameText que se le pasa como parámetro cambiando su texto por el valor del campo que representa el tag.

endFFrameText()

Recupera el texto que inicialmente tenían todos FFrameText.

askAll()

Abre el diálogo que pregunta si se quieren madar a la cola de impresión todas las fichas que se generan .

askOne()

Abre el diálogo que pregunta si la ficha que se esta visualizando se quiere imprimir.

askOne.java

Diálogo para preguntar si se quiere imprimir la ficha que se visualiza en ese momento en pantalla.

askAll.java

Diálogo para preguntar si se quieren imprimir todas las fichas que se generen.

Iver-utilies.jar

Librería utilizada en nuestro caso para clonar FFrames.

gdbms.jar

Librería utilizada para acceder a los drivers.

config.xml

Fichero XML utilizado para añadir a ANDAMI la extensión.

<?xml version="1.0" encoding="ISO-8859-1"?>

<plugin-config>

      <libraries library-dir="."/>

            Dependencias con otras extensions para que sean cargadas con anterioridad, en nuestro caso la dependencia es con gvSIG.

<depends plugin-name="com.iver.cit.gvsig"/>

            <resourceBundle name="text"/>

      <extensions>

                        Nombre de la Extensión, descripción y si esta activa o no lo está.

            <extension class-name="com.iver.templateLayout.TemplateExtension"

                  description="Extensión de ejemplo que genera una ficha por cada shape seleccionado,

                        cambiando los tag por su valor."

                  active="true">

                                    Opción de menú necesaria para esta extensión con su comando, tecla de activación rápida, icono, texto tooltip, y posición.

                  <menu text="mapa/crear_ficha" action-command="create" key="t"

                        mnemonic="c" icon="images/template.gif"

                        tooltip="crear_ficha"

                        position="1"/>

                                   Barra de herramientas, que según su nombre si ya ha sido creada por otra extensión, no se vuelve a crear.

                  <tool-bar name="Herramientas">

                                                Botón necesario para esta extensión, con su comando, texto tooltip, texto de deshabilitado.

                        <action-tool icon="images/template.gif"

                             action-command="create" tooltip="crear_ficha"

                             enable-text="debería de estar activada" last="true"/>

                  </tool-bar>

            </extension>

      </extensions>

</plugin-config>

Directorio images

En este directorio se almacenan las imágenes necesarias para el Plugin.

Directorio lib

Directorio dedicado para almacenar las librerías utilizadas por el plugin.

build.xml

Fichero Ant, utilizado para copiar al directorio de gvSIG/extensiones las clases y librerías necesarias, así como los ficheros e imágenes de una forma automática. También es posible copiarlas manualmente o con cualquier otra herramienta.

Ficheros *.properties

Son los ficheros con toda la información para la traducción del plugin. El nombre de estos ficheros de traducción tienen que seguir esta forma:

El nombre tiene que estar compuesto por "text_" más la abreviatura que el Locate de java se reserva para este idioma y siempre con la extensión ".properties". En el caso de español sería:

text_es.properties

Pero se tiene un idoma por defecto con el nombre:

text.properties

Cada uno de estos ficheros contiene la traducción a un idioma, y la forma de guardarse esa información es:

"Clave" = "traducción"

La "Clave" debe ser la misma en todos los ficheros de traducción de todos los lenguajes que incorporemos y la "traducción" debe de ser la del idioma dedicado por este fichero en concreto.