ZUI - Swing made easy

SourceForge.net Logo

Newsfeed Lesser GPL License Valid XHTML 1.0! Valid CSS!

tutorial

ATENCIÓN: Este tutorial todavía está en desarrollo, puede contener errores y partes incompletas.

índice

  1. esquema general de uso
  2. definición del xml
  3. widgets básicos
  4. posicionamiento de widgets
  5. menús
  6. tablas
  7. árboles
  8. creación de eventos
  9. look & feel
  10. localización de textos

esquema general de uso

Partiendo del ejemplo de la página principal, podemos obtener el siguiente diagrama:

Figura 1

Este diagrama muestra las tres reglas que hay que seguir para usar ZUI:

  1. El nombre del documento xml y el de la clase debe ser el mismo incluyendo mayúsculas/minúsculas. Además, deben estar situados en el mismo paquete.
  2. Para poder obtener la referencia de un widget hay que:
    • definir un atributo id en el xml al widget que queremos referenciar
    • usar el método getWidget() pasándole dicho identificador por parámetro
  3. Para definir acciones hay que
    • Definir el método java que recibirá el evento
    • Definir en el xml el evento indicando el nombre del método que lo recibirá

Nada más. Ahora sólo hay que conocer los nombres de los elementos xml que definen cada uno de los widgets así como los atributos y métodos que hay disponibles para cada uno de ellos.

(subir)

definición del xml

El formato general de cualquier xml de ZUI es:

<?xml version="1.0"?>
<zui>
  ...
</zui>

El elemento zui siempre es la raiz del documento independientemente de que se utilice para ser usado como base para definir un frame, un dialog, un applet o que sea referenciado mediante include.

Por ejemplo, para el documento Ventana.xml definido de la siguiente forma:

<?xml version="1.0"?>
<zui title="Nombre" width="256" height="144">
  ...
</zui>

Este xml podría ser referenciado desde java de las siguientes dos formas:

// Definiendo una clase que extienda ZFrame
// cuyo nombre sea el mismo que el del documento
public class Ventana extends ZFrame {
...
}

// Definiendo una clase que extienda ZDialog
// cuyo nombre sea el mismo que el del documento
public class Ventana extends ZDialog {
...
}

Además, es posible referenciar el archivo Ventana.xml desde otro xml de la siguiente forma:

<?xml version="1.0"?>
<zui ...>
  ...
  <include src="Ventana.xml"/>
  ...
</zui>

De esta forma se puede dividir un xml en varias partes más manejables. Por ejemplo, si tenemos una ventana con un tabbedpane que contiene pestañas, cada una de ellas podemos definirla en un archivo xml diferente de la siguiente forma:

DemoInclude.xml

<?xml version="1.0"?>
<zui title="Ventana">
  ...
  <tabbedpane selected="1">
    <include src="tab1.xml"/>
    <include src="tab2.xml"/>
    <tab name="Tab3" />
    <tab name="Tab4" />
  </tabbedpane>
  ...
</zui>

tab1.xml

<?xml version="1.0"?>
<zui name="Tab1">
  <label text="label_tab1"/>
</zui>

tab2.xml

<?xml version="1.0"?>
<zui name="Tab2">
  <label text="label_tab2"/>
</zui>

En este caso el tag zui actúa de comodín y toma el valor que espera el tabbedpane que en este caso es tab. También es posible utilizar include sin estar dentro de widgets compuestos, por ejemplo:

DemoInclude.xml

<?xml version="1.0"?>
<zui title="Ventana">
  ...
  <label text="etiqueta1"/>
  <include src="etiqueta2.xml"/>
  <label text="etiqueta3"/>
  ...
</zui>

etiqueta2.xml

<?xml version="1.0"?>
<zui>
  <label text="etiqueta3"/>
</zui>

En cuyo caso el tag zui no se utiliza y simplemente actúa de contenedor general.

(subir)

widgets básicos

Para explicar mejor el funcionamiento de ZUI vamos a ir construyendo un ejemplo práctico de un formulario de introducción de datos de un cliente.

Figura 2

crear una ventana

Lo primero que vamos a hacer es crear un archivo llamado Widgets.xml y le vamos a indicar que queremos una ventana con el título Datos cliente le asignamos ancho y alto e indicados que esté centrada en la pantalla.

<?xml version="1.0"?>
<zui title="Datos cliente" width="400" height="250" centered="true">
</zui>

Ahora vamos a declarar una clase java llamada Widgets, que extienda de ZFrame y que esté en el mismo paquete que el xml. Vamos a incluirle un main para que cree una nueva instancia y la haga visible.

import net.sf.zui.ZFrame

public Widgets extends ZFrame {
...
  public static void main(String []args) {
    Widgets w = new Widgets();
    w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    w.setVisible(true);
  }
}

Ya se podría ejecutar la aplicación aunque sólo obtendríamos una ventana vacía centrada en la pantalla.

label

Vamos a introducir ahora las etiquetas de los campos que va a tener el formulario:

<?xml version="1.0" encoding="ISO-8859-1"?>
<zui title="Datos cliente" width="400" height="250" centered="true">
  <label text="Nombre:"/>
  <label text="Apellidos:"/>
  <label text="Sexo:"/>
  <label text="Dirección:"/>
  <label text="Provincia:"/>
</zui>

Si ejecutamos ahora la aplicación obtenemos la siguiente imagen

Figura 3

button

Incluimos la botonera para lo cual creamos un panel al que indicamos que tiene 3 columnas. En la primera columna contiene un separador cuyo ancho es el máximo que permitan las otras dos columnas cada una de las cuales contiene un botón.

<panel contentLayout="cols=3">
  <separator layout="cspan=3"/>
  <separator visible="false" layout="cweight=1"/>
  <button text="Aceptar"/>
  <button text="Cancelar"/>
lt;/panel>

Figura 4

Como se puede ver, los botones son demasiado altos y cada una de las líneas de datos también. Esto se soluciona incluyendo un separador cuyo alto sea el máximo posible y que sea invisible justo antes del panel.

Figura 5

textfield, combobox y radiobutton

Por último le añadimos los campos de entrada con los que interactuará el usuario. Para ello indicamos a la ventana que va a tener dos columnas, la de la izquierda contendrá las etiquetas y la derecha contendrá los campos de entrada de datos.

Los radiobuttons

<?xml version="1.0" encoding="ISO-8859-1"?> <zui title="Datos cliente" width="400" height="250" centered="true"
     contentLayout="cols=2">
  <label text="Nombre:"/><textfield id="nombre" layout="cweight=1"/>
  <label text="Apellidos:"/><textfield id="apellidos"/>
  <label text="Sexo:"/>
  <panel contentLayout="cols=2">
    <radio text="Hombre" group="sexo"/>
    <radio text="Mujer" group="sexo" layout="w cweight=1"/>
  </panel>
  <label text="Dirección:"/><textfield id="direccion"/>
  <label text="Provincia:"/>
  <combobox id="provincia">
    <item text="" value=""/>
    <item text="Alicante" value="alc"/>
    <item text="Barcelona" value="bcn"/>
    <item text="Madrid" value="mad"/>
  </combobox>
  <separator visible="false" layout="cspan=2 rweight=1"/>
  <panel layout="cspan=2" contentLayout="cols=3">
    <separator layout="cspan=3"/>
    <separator visible="false" layout="cweight=1"/>
    <button text="Aceptar"/>
    <button text="Cancelar"/>
  </panel>
</zui>

Finalmente obtenemos la ventana que queremos.

Figura 6

(subir)

posicionamiento de widgets

ZUI utiliza un Layout Manager específico llamado TableLayout creado por Tony Freixas y cuyo código está bajo licencia Artistic License. Todo este punto de la ayuda se ha obtenido de la página de TableLayout:

atributos disponibles

Existen dos atributos llamados contentLayout y layout que se utilizan para posicionar los widgets. El primero, contentLayout, se usa en los contenedores para definir cómo posicionar los widgets hijos. El segundo layout lo puede utilizar cualquier widget para definir datos específicos de posicionamiento de ese widget.

Los valores de esos atributos se especifican de la siguiente forma:

<container contentLayout="atr1=val1 atr2=val2 ...">...

<widget layout="atr1=val1 atr2=val2 ...">...

En donde atr1, atr2, ... puede ser cualquier nombre de la primera columa de la siguiente tabla:

nombredescripciónvalor por defectoámbito
colsnúmero de columnas1contentLayout
colsitúa el widget en esta columnasiguiente columna vacíalayout
skipsalta un número de columnas0layout
rspan, cspanunión de filas y columnas1layout
titop, tibottom, tileft, tirighttable insets0contentLayout
rgap, cgapgaps de filas y columnas0contentLayout
itop, ibottom, ileft, irightinsets del widget0contentLayout, layout
tn, tne, te, tse, ts, tsw, tw, tnw, tc, tf, tfh, tfvsituación del panel y rellenadotfcontentLayout
n, ne, e, se, s, sw, w, nw, c, f, fh, fvsituación del widget y rellenadofcontentLayout, layout
rweight, cweightpeso de la fila y de la columna0contentLayout, layout

ejemplo básico

Éste es el caso más simple en el que indicamos que el panel va a estar formado por 3 columnas. Todos los botones se van colocando en la siguiente columna libre, cuando se llenan las 3 columnas se empieza a rellenar la línea siguiente.

<panel contentLayout="cols=3">
  <button text="0"/>
  <button text="1"/>
  <button text="2"/>
  <button text="3"/>
  <button text="4"/>
</panel>

Figura 7

filas y columnas

<panel contentLayout="cols=3">
  <button text="0"/>
  <button text="1" layout="skip=1"/>
  <button text="2" layout="col=1"/>
  <button text="3" layout="rspan=2"/>
  <button text="4" layout="cspan=2"/>
</panel>

Figura 8

espaciado

<panel contentLayout="cols=3 rgap=3 cgap=3 titop=5 tibottom=5 tileft=5 tiright=5 itop=2 ibottom=2 ileft=2 iright=2">
  <button text="0"/>
  <button text="1" layout="skip=1"/>
  <button text="2" layout="itop=0 ibottom=0 ileft=0 iright=0 col=1"/>
  <button text="3" layout="rspan=2"/>
  <button text="4" layout="cspan=2"/>
</panel>

Figura 9

posicionamiento y relleno

<panel contentLayout="cols=3">
  <button text="1" layout="nw"/>
  <button text="2" layout="n"/>
  <button text="3" layout="ne"/>
  <button text="4" layout="w"/>
  <button text="5" layout="c"/>
  <button text="6" layout="e"/>
  <button text="7" layout="sw"/>
  <button text="8" layout="s"/>
  <button text="9" layout="se"/>
</panel>

Figura 10

<panel contentLayout="cols=3 tnw">
  <button text="1" layout="nw"/>
  <button text="2" layout="n"/>
  <button text="3" layout="ne"/>
  <button text="4" layout="w"/>
  <button text="5" layout="c"/>
  <button text="6" layout="e"/>
  <button text="7" layout="sw"/>
  <button text="8" layout="s"/>
  <button text="9" layout="se"/>
</panel>

Figura 11

<panel contentLayout="cols=3">
  <button text="1" layout="c fh"/>
  <button text="2" layout="f"/>
  <button text="3" layout="c fh"/>
</panel>

Figura 12

<panel contentLayout="cols=5">
  <button text="0"/>
  <button text="1"/>
  <button text="2"/>
  <button text="3"/>
  <button text="4"/>
</panel>

Figura 13

<panel contentLayout="cols=5">
  <button text="0"/>
  <button text="1" layout="cweight=1"/>
  <button text="2"/>
  <button text="3" layout="cweight=1"/>
  <button text="4"/>
</panel>

Figura 14

(subir)

menús

Para definir menús se pueden utilizar los elementos menubar, menu, menuitem y menuseparator.

menubar define una barra de menús. Sólo se puede definir una barra de menú por ventana y ésta ha de hacerse situando el elemento menubar como hija del elemento zui que es el que define la ventana (frame, dialog o applet).

A continuación, podemos definir tantos menu y menuitem como se deseen pudiendo realizar anidamientos si así se necesitase. Así mismo, se puede utilizar menuseparator para realizar separaciones dentro de menús.

Importante: el elemento menubar NO ha de tenerse en cuenta a la hora de definir los layouts, por ejemplo cuando se definen el número de columnas que tiene una ventana.

<?xml version="1.0" encoding="ISO-8859-1"?>
<zui title="Demo menu" width="400" height="250" contentLayout="cols=3">
  <menubar>
    <menu text="Archivo" mnemonic="A">
      <menuitem text="Abrir" mnemonic="b" onAction="doMenuAbrir"/>
      <menuitem text="Guardar" mnemonic="G" onAction="doMenuGuardar"/>
      <menuitem text="Guardar como..." mnemonicChar="c"/>
      <menuseparator/>
      <menu text="Recientes">
        <menuitem text="Reciente 1"/>
        <menuitem text="Reciente 2"/>
        <menuitem text="Reciente 3"/>
      </menu>
      <menuseparator/>
      <menuitem text="Salir"/>
    </menu>
  </menubar>
  <!-- menubar NO cuenta como columna 1 en el layout de la ventana -->
  ...
</zui>

Figura 15

(subir)

tablas

ZUI tiene implementado un TableModel propio que facilita el uso de tablas, tanto a nivel de definición en el XML como de uso dentro del código Java.

Los elementos necesarios para componer tablas son table para definir una tabla, head para indicar que vamos a declarar las columnas de la tabla, row por cada una de las filas que queramos incluir por defecto en la tabla y col por cada celda que haya tanto dentro de head como dentro de row.

En el siguiente ejemplo tenemos una tabla y un botón; cuando se selecciona una fila de la tabla se lanza un evento que activa el botón.

<table id="listaClientes" sorted="true" onListSelection="selectCliente">
  <head>
    <col text="Id" width="10" visible="false" alignment="right"/>
    <col text="Nombre" width="200" editable="false"/>
    <col text="Apellidos" width="200" editable="false"/>
  </head>
  <row>
    <col text="40"/>
    <col text="José Miguel"/>
    <col text="Sanz García"/>
  </row>
</table>
...
<button id="editarClienteButton" enabled="false"/>

public final void selectCliente(final ListSelectionEvent e) {
  // Habilito el botón de edición del cliente
  JButton button = (JButton) this.getWidget("editarClienteButton");
  button.setEnabled(true);
}

(subir)

árboles

Este widget todavía no está implementado

(subir)

creación de eventos

(subir)

look & feel

(subir)

localización de textos