Pedir datos al usuario con IzPack

De ChuWiki

Partimos del Ejemplo sencillo con izpack en el que hicimos lo mínimo para construir un instalador de una aplicación nuestra usando IzPack. En dicho instalador se instalaba nuestra aplicación y opcionalmente se instalaba la documentación de la misma. Dicha documentación se instalaba en el subdirectorio "doc". Vamos ahora a añadir un panel al instalador que permita al usuario elegir el nombre de ese directorio.

El panel del usuario[editar]

Lo primero que tenemos que hacer es definir el panel en el que le preguntaremos al usuario el nombre del directorio. Será como el de esta figura

Para definir este panel usaremos un fichero xml de nombre el que queramos, por ejemplo, userinput.xml cuyo contenido es este

<userInput>
  <panel order="0">
     <createForPack name="documentacion"/>
     <field type="text" variable="nombreDirectorio">
        <spec txt="Nombre para el directorio de documentacion" size="25" set="doc"/>
   </field>
  </panel>
</userInput>

Un tag inicial <userinput>. Dentro podremos definir varios paneles identificador por el atributo order, que será 0, 1, 2, etc. En este ejemplo sólo hemos definido uno que es <panel order="0">

El siguiente tag es <createForPack name="documentacion">. Aquí estamos indicando que sólo queremos este panel si el usuario elige instalar el paquete de documentación. En name debe ser el mismo que habíamos puesto en el fichero instalacion.xml en el <pack name="documentacion" ...>. Si en el panel no ponemos tag <createForPack...>, este panel saldrá siempre, independientemente de qué paquetes pida el usuario.

Ahora tenemos que ir declarando los campos que queremos que tenga el panel a base de tags <field>. El atributo type indica de qué tipo es el campo. En este caso, <field type="text"...> es para un campo de texto en el que el usuario podrá escribir. Aquí tienes un listado con todos los posibles campos que admite IzPack.

Cada campo debe llevar una variable="nombreVariable", que es donde se almacenará la entrada del usuario. En este caso, hemos puesto <field type="text" variable="nombreDirectorio">, de forma que lo que el usuario escriba en la caja de texto se guardará en la variable "nombreDirectorio". Más adelante podremos acceder a su contenido poniendo un $ delante, así $nombreDirectorio.

El tag <field> admite tags <spec> para añadir detalles a este campo de texto. Hemos puesto:

  • txt="Nombre para el directorio de documentacion" : Una etiqueta delante del campo para que el usuario sepa qué tiene que meter
  • size="25" : un tamaño para el campo de texto
  • set="doc" : un valor inicial para mostrar dentro del campo de texto

y esto es todo, cerramos todos los tag xml que se han ido abriendo y listo.

Incluir el panel del usuario en el instalador[editar]

Ahora, en el fichero instalacion.xml debemos indicar que queremos que se muestre este panel. Para ello, ponemos el tag <resources> indicando el nombre del fichero xml donde hemos definido el panel

<installation version="1.0">
   ...
   <resources>
      <res id="userInputSpec.xml" src="userinput.xml" />  
   </resources>
   ...
</installation>

donde id="userInputSpec.xml" es fijo y debe ir así, indicando a IzPack que el recurso corresponde a los paneles de usuario. En src="userinput.xml" ponemos el nombre de nuestro fichero xml con el panel, por supuesto, con el path adecuado para encontrarlo, que en este caso es en el mismo directorio de ejecución de IzPack.

También debemos incluir la clase "UserInputPanel" entre las clases de los paneles a mostrar, indicando el número de order del panel (¿recuerdas que al panel le pusimos order="0"?. Pues eso)

<installation version="1.0">
   ...
   <panels>
      <panel classname="HelloPanel"/>
      <panel classname="PacksPanel"/>
      <panel classname="UserInputPanel" id="UserInputPanel.0"/>
      <panel classname="TargetPanel"/>
      <panel classname="InstallPanel"/>
      <panel classname="FinishPanel"/>
   </panels>
   ...
</installation>

Hemos puesto id="UserInputPanel.0" indicando que queremos el panel 0. Tenemos que tener la precaución de poner este panel antes del sitio en el que se vayan a usar las variables en él definidas. En este caso, como pedimos en directorio de instalación y este se creará en el "InstallPanel", debemo poner el "UserInputPanel" antes del "InstallPanel".

Recoger los datos del UserInputPanel[editar]

Ahora, en el paquete de documentacion, debemos poner el directorio que el usuario ha indicado en el UserInputPanel. Este directorio introducido por el usuario, si recuerdas, quedaba guardado en la variable nombreDirectorio. Entonces, el tag <file> donde se indica que el directorio de documentacion va a "doc"

      <pack name="documentacion" required="no">
         <description>La documentacion</description>
         <file src="APLICACION/doc" targetdir="$INSTALL_PATH/doc"/>
      </pack>

debemos cambiarlo por la variable $nombreDirectorio

      <pack name="documentacion" required="no">
         <description>La documentacion</description>
         <file src="APLICACION/doc" targetdir="$INSTALL_PATH/$nombreDirectorio"/>
      </pack>

esto, sin embargo, no nos vale, porque si por ejemplo el usuario escribió "manuales", se nos creará esto

$INSTALL_PATH/manuales/doc/...

es decir, crea el directorio manuales y mete dentro el subdirectorio doc de nuestra aplicación. Para evitar esto, usaremos <fileset> en vez de <file>, así

      <pack name="documentacion" required="no">
         <description>La documentacion</description>
         <fileset dir="APLICACION/doc" targetdir="$INSTALL_PATH/$nombreDirectorio"/>
      </pack>

<fileset> incluye todos los ficheros dentro de doc, pero no doc mismo, y los mete en $INSTALL_PATH/$nombreDirectorio, que es lo que queríamos.