OpenLaszlo: Una plataforma para construir e implementar rápidamente aplicaciones de Internet enriquecidas

Comprenda qué es OpenLaszlo y cómo simplifica la manera de desarrollar e implementar aplicaciones de Internet enriquecidas

Conozca a OpenLaszlo, una plataforma de código abierto, ofrecida bajo la Licencia Pública Común (Common Public LIcense o CPL), para el desarrollo y la entrega de aplicaciones de Internet enriquecidas (RIA por su sigla en inglés). OpenLaszlo se basa en LZX, un lenguaje orientado a los objetos que usa XML y JavaScript. Las aplicaciones enriquecidas de clientes escritas con OpenLaszlo se ejecutan en diversos navegadores y varias plataformas. En este artículo, nos ocuparemos de la arquitectura y las API de OpenLaszlo con numerosos ejemplos. Además, analizaremos las herramientas de depuración básicas.

Kumarsun Nadar, Senior Staff Software Engineer, IBM

Photo of KumarsunKumarsun Nadar es Senior Staff Software Engineer en los IBM India Software Labs (ISL) del equipo de productos WebSphere Business Service Fabric, en las afueras de Mumbai, India. Dentro de este equipo, participó en el desarrollo de UI del módulo Fabric Web Tools, basado en el marco Wicket. Obtuvo certificaciones de SUN Microsystems en SCJP, SCWCD y SCBCD y tiene experiencia en diversas tecnologías para clientes y servidores como por ejemplo Wicket, EJB, Hibernate, Struts, etc., basadas en la plataforma Java/J2EE. Entre sus hobbies se incluyen mirar y jugar deportes como cricket y tenis de mesa.



29-07-2011

Generalidades

Uno de los mayores desafíos que enfrentan los desarrolladores de RIA es el de la compatibilidad de navegadores. Debido a que OpenLaszlo se basa en el paradigma del lenguaje Java™ de escribir una vez y ejecutar en todos lados, se asegura que las aplicaciones basadas en OpenLaszlo se ejecutan de manera uniforme en diversos navegadores de múltiples sistemas operativos.


Arquitectura

La siguiente figura muestra el lado del servidor y la arquitectura del lado del cliente de OpenLaszlo.

Figura 1. Servidor OpenLaszlo y subsistemas de los clientes
Servidor OpenLaszlo y subsistemas de los clientes

Servidor OpenLaszlo

El Servidor OpenLaszlo es una aplicación Java servlet/JSP. Este servidor facilita en gran medida el desarrollo de aplicaciones LZX.

El servidor OpenLaszlo consta de cinco subsistemas principales:

  • Interface Compiler (Compilador de interfaces)— El Interface Compiler consiste en un LZX Tag Compiler (Compilador de Etiquetas LZX) y un Script Compiler (Compilador de Scripts), que convierten los archivos de origen en archives ejecutables (SWF) y los ofrecen como un bytecode para un complemento que se ejecuta en el navegador del cliente (como por ejemplo Flash o J2ME), o como un JavaScript (DHTML) ejecutado por el mismo navegador.
  • Media Transcoder (Transcodificador de medios)— Media Transcoder convierte una completa variedad de recursos de medios a un único formato para que sea renderizado por el motor de renderización de clientes objetivo de OpenLaszlo. Esto permite que una aplicación de OpenLaszlo presente tipos de medios compatibles de una manera unificada en un mismo lienzo, sin múltiples aplicaciones auxiliares ni software de repetición suplementario. Media Transcoder automáticamente presenta los siguientes tipos de medios: JPEG, GIF, PNG, MP3, TrueType, y SWF (sólo arte/animación).
  • Data Manager (Administrador de datos)— Data Manager funciona como una interfaz entre las aplicaciones de OpenLaszlo y otras aplicaciones de la red, como por ejemplo bases de datos y servicios web XML. Consiste en un compilador de datos que convierte los datos a un formato binario comprimido y una serie de conectores de datos que permiten a las aplicaciones de OpenLaszlo recuperar estos datos por medio de XML/HTTP.
  • Cache— El Cache contiene la versión más recientemente compilada de cualquier aplicación. La primera vez que se solicita una aplicación de OpenLaszlo, la misma es compilada y se envía al cliente el archivo SWF resultante. En el servidor se almacena una copia como cache, por lo cual las sucesivas solicitudes no tendrán que esperar que se realice la compilación.

El cliente OpenLaszlo

La arquitectura del lado del cliente de OpenLaszlo consiste fundamentalmente en las clases de la Laszlo Foundation, que brindan el entorno en tiempo de ejecución para ejecutar las aplicaciones de OpenLaszlo. Cada vez que un cliente invoca una aplicación de OpenLaszlo mediante sus URL, también se descargan las bibliotecas necesarias y la fuente en tiempo de ejecución. El cliente mantiene en todo momento una conexión con el servidor.

El cliente OpenLaszlo consta de los siguientes subsistemas principales

  • Event System (Sistema de eventos)— Event System es responsable del manejo de diversos eventos basados en el usuario, como por ejemplo los clics del mouse y los envíos de datos. Además, mejora el rendimiento de una aplicación al realizar diversas operaciones en el lado del cliente, como por ejemplo las de clasificación y validación, en lugar de pasarlas al servidor.
  • Data Loader/Binder (Cargador/Enlazador de Datos)— Data Loader recibe los datos despachados desde el lado del servidor y los vincula con sus respectivos elementos de UI, como menús, campos de texto y áreas de texto en el lado del cliente.
  • Layout and Animation System (Sistema de Disposición y Animación)— Layout and Animation System maneja numerosos algoritmos relacionados con la animación, permitiendo al usuario la visualización de los componentes de una manera continua desde el punto de vista visual. Además, controla la posición de diversos componentes usando un posicionamiento de píxeles absoluto y relativo con mínima programación.

Ciclo de solicitudes

El flujo típico de solicitudes toma la siguiente ruta:

  1. El usuario envía una solicitud de un recurso en forma de URL a través del navegador.
  2. El servidor de OpenLaszlo recupera el recurso basado en el URL y lo envía al Interface Compiler para su compilación.
  3. El Interface Compiler convierte las etiquetas y los JavaScripts de la descripción de la aplicación LZX en un bytecode ejecutable (SWF) para su transmisión al entorno del cliente de OpenLaszlo. Este código es colocado en el caché, y desde allí es enviado al cliente.
  4. Según cómo se invoque la aplicación, la misma es transmitida como un archivo SWF o como un archivo HTML con un objeto SWF incrustado, junto con las clases de la Laszlo Foundation adecuadas.
  5. El navegador es el que muestra la aplicación en el caso de una respuesta con formato HTML. El reproductor de Flash es el que reproduce la aplicación en el caso de una respuesta con formato SWF.
  6. El usuario ingresa ciertos datos de la solicitud desde el lado del cliente y envía estos datos.
  7. El servidor OpenLaszlo invoca al conector de datos adecuado, y éste, a su vez, toma los datos XML.
  8. El servidor OpenLaszlo envía los datos nuevamente al cliente.
  9. Las clases de la Laszlo Foundation en el lado del cliente se enlazan los datos a los objetos de UI adecuados. Los elementos de la pantalla se actualizan con los datos de la respuesta.

La Figura 2 muestra un típico ciclo de solicitud de aplicaciones de OpenLaszlo según lo descripto anteriormente.

Figura 2. Ciclo de solicitud
Ciclo de solicitud

Su primera aplicación OpenLaszlo

El desarrollo de una aplicación OpenLaszlo implica:

  • Escribir el programa OpenLaszlo (en XML y JavaScript) usando un editor de texto.
  • Guardar el archivo como un archivo LZX.
  • Compilar el archivo LZX a un archivo SWF o DHTML, ya sea manualmente o usando el servidor OpenLaszlo y visualizando el resultado en el navegador.

Cómo escribir una aplicación de OpenLaszlo

Como se mencionara anteriormente, una aplicación de OpenLaszlo es un documento XML. Por lo tanto, usted puede usar cualquier editor de texto para escribir su código. El código del Listado 1 corresponde a una aplicación simple de HelloWorld LZX.

Listado 1. HelloWorld.lzx
<canvas height="350" width="1050" bgcolor="#FFBE7D" > 
<view width="500" height="250" align="center" valign="middle" bgcolor="#FFFF66"> 
<text align="center" valign="middle">
<font size="25">Welcome to
Hello World!</font> </text> </view>
</canvas>

Cómo guardar el archivo de origen

Ahora, guarde el script como HelloWorld.lzx. Se debe guardar el archivo en algún lugar del directorio Server/lps-4.0.x, que se encuentra en el directorio de instalación del servidor OpenLaszlo.

Cómo compilar y ejecutar el script

La manera más fácil de compilar un archivo LZX es usando el servidor OpenLaszlo. Asegúrese de que en su computadora funciona Apache Tomcat y dirija el navegador a la siguiente URL: http://localhost:8080/lps-4.0.x/path. Aquí,path es la ruta al archivo LZX relacionado con el directorio Server/lps-4.0.x.

Por ejemplo, si el script se guarda como Server/lp2-4.0.x/hello/HelloWorld.lzx, la URL para compilar la aplicación de OpenLaszlo será http://localhost:8080/lps-4.0.x/hello/HelloWorld.lzx, que se muestra en la Figura 3. El contenedor del servlet pasará la solicitud de HTTP al servidor OpenLaszlo. El servidor se abre y compila el archivo LZX correcto, genera la respuesta y la guarda en un directorio temporario.

El servidor OpenLaszlo luego envía la respuesta generada al navegador. Si la aplicación está compilada como Flash, el archivo SWF generado y los archivos relacionados se modificar serán mucho más rápidas debido a que no será necesario realizar ninguna compilación. Si falla la compilación, el navegador mostrará un mensaje de error.

Figura 3. Ejemplo de aplicación hello world de OpenLaszlo
Ejemplo de aplicación hello world de OpenLaszlo

La parte inferior muestra una herramienta de desarrollo que contiene botones que le permiten visualizar su código fuente de OpenLaszlo, implementar su aplicación, recopilar el código fuente y realizar otras funciones. La herramienta de desarrollo puede evitarse si se pasa el tipo de solicitud correcta y el objetivo de tiempo de ejecución como parámetros. Por ejemplo:

http://127.0.0.1:8080/lps-4.3.0/helloWorld/HelloWorld.lzx?lzr=swf9&lzt=html
http://127.0.0.1:8080/lps-4.3.0/helloWorld/HelloWorld.lzx?lzr=dhtml&lzt=html

La Figura 4 muestra un ejemplo de la aplicación helloWorld ejecutada con parámetros para suspender la barra de herramientas.

Figura 4. Ejemplo de aplicación Hello World de OpenLaszlo
Ejemplo de aplicación Hello World de OpenLaszlo

Componentes básicos

OpenLaszlo viene con un conjunto de clases que representan componentes simples y ricos, lo cual facilita y agiliza la programación. La clase BaseComponent es una subclase de LzView y la superclase de todos los componentes LZX.

Lienzo

La etiqueta canvas (lienzo)( representa el principal contendor de todas las vistas y los elemen de una aplicación LZX. Hay exactamente un lienzo por cada aplicación LZX. La clase LzCanvas se ejemplifica cuando el compilador de LZX encutosentra la etiqueta canvas. Por ejemplo, el código del Listado 2 muestra cómo se usa la etiquetacanvas y algunos de sus atributos.

Listado 2. Canvas.lzx
<canvas width="450" bgcolor="#6699FF" height="200"
title="Canvas"> <text align="center" valign="middle">
<font size="25">Openlaszlo World!</font>
</text> </canvas>

La aplicación anterior puede invocarse usando http://localhost:8080/lps-4.0.x/canvas/Canvas.lzx. La Figura 5 muestra el resultado que se genera.

Figura 5. Lienzo
Lienzo

Vista

Una vista representa un área rectangular que puede mostrar texto y otros elementos. Usted puede crear una vista usando la etiqueta view o ejemplificando la clase LzView. A modo de ejemplo, el Listado 3 muestra una aplicación LZX que usa la etiqueta view.

Listado 3. View.lzx
<canvas width="300"
bgcolor="#ddddee" height="200"> <view align="center" valign="middle"
bgcolor="#6699FF" width="300" height="150"/>
</canvas>

La aplicación anterior puede verse usando http://localhost:8080/lps-4.0.x/view/View.lzx. La Figura 6 muestra el resultado generado a partir del archivo view.lzx.

Figura 6. Cómo usar View
Cómo usar View

En una típica aplicación LZX, usted usará a menudo múltiples vistas, cada una de ellas anidada dentro de otra. El Listado 4 muestra una aplicación LZX con vistas anidadas.

Listado 4. NestedView.lzx
<canvas
height="370"> <view width="150" height="150" bgcolor="black">
<view width="100" height="100" bgcolor="white"> <view
width="50" height="50" bgcolor="gray"/> </view>
</view> </canvas>

La aplicación anterior se puede invocar navegando a http://localhost:8080/lps-4.0.x/view/NestedView.lzx. La Figura 7 muestra el resultado que se genera.

Figura 7. Cómo usar las vistas anidadas
Cómo usar las vistas anidadas

También es posible usar la etiquetaviewpara mostrar o reproducir recursos externos, como por ejemplo imágenes, archivos MP3, y otros archivos Flash. Los tipos de medios soportados son JPG, GIF, PNG, MP3, y SWF. Observe que el soporte para MP3 se limita a archivos de audio tomados en 44.1 KHz, 22 KHz, 11 KHz, 8 KHz, y 5.5 KHz. El Listado 5 muestra un ejemplo de una aplicación LZX que usaviewpara mostrar una imagen.

Listado 5. ResourceView.lzx
<canvas width="300" bgcolor="#ddddee"
height="200"> <view align="center" resource="IBMLogo.jpg"
valign="middle" bgcolor="#6699FF" width="300" height="150"/>
</canvas>

La aplicación anterior se puede invocar usando http://localhost:8080/lps-4.0.x/view/ResourceView.lzx. La Figura 8 muestra el resultado generado.

Figura 8. Cómo usar la vista Resource
Cómo usar la vista Resource

Ventana

Un objeto Window (Ventana) representa una ventana ajustable. La clase Window es una subclase de WindowPanel, que es una sibclase de BaseWindow. BaseWindow es un element secundario directo de BaseComponent. El archivo Window.lzx del Listado 6 es una aplicación LZX que muestra una ventana ajustable.

Listado 6. Window.lzx
<canvas width="450" bgcolor="#6699FF" height="200"
title="Canvas"> <window align="center" valign="middle"
resizable="true" width="300" height="150"> <text>OpenLaszlo
World!</text> </window>
</canvas>

La aplicación anterior se puede invocar con http://localhost:8080/lps-4.0.x/window/Window.lzx. La Figura 9 muestra el resultado generado.

Figura 9. Window
Window

Alerta

Un objeto Alert (Alerta) representa un casillero Modal Dialog para mostrar un mensaje. El casillero de Alerta viene equipado con un botón de OK. No se muestran de manera predeterminada. Usted debe llamar al método open (abrir) de la alerta para hacerla visible. La clase Alert es una subclase de la clase ModalDialog, que deriva de WindowPanel. Un objeto A Modal Dialog representa una vista flotante movible. El código del Listado 7 muestra cómo usar el casillero Alert.

Listado 7. Alert.lzx
<canvas> <alert
name="warning">Press OK to continue.</alert>
<script> canvas.warning.open (); </script>
</canvas>

La aplicación anterior puede invocarse con http://localhost:8080/lps-4.0.x/alert/Alert.lzx. La Figura 10 muestra el resultado generado.

Figura 10. Casillero Alert
Casillero Alert
Listado 8. AlertWithButtons.lzx
<canvas> <alert
name="warning" buttonl="OK" button2="No"> Click OK to Process.
<handler name="onresult"> if (this.result) {
parent.message.setText("Processing Started"); } else { parent.message.setText
("Processing Stopped'"); } </handler> </alert>
<script> canvas.warning.open (); </script> <text
name="message"> Do you want to start processing?</text>
</canvas>

AlertWithButtons pide confirmación del usuario en forma de un casillero de alerta con botones Yes/No (Sí/No) y toma la medida adecuada.

Button

Un objeto botón representa un botón sobre el que se puede presionar, que hace surgir un evento, de manera que usted pueda realizar una acción con un clic. Esta clase es una subclase de BaseButton, que a su vez, es una subclase de BaseComponent. El archivo Button.lzx del Listado 9 es una aplicación LZX que usa un botón. El texto del botón dice: "Hello World!!"

Listado 9. Button.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <button width="200" height="80" align="center"
valign="middle"> Hello World!!</button>
</canvas>

Ejecute el ejemplo navegando a http://localhost:8080/lps-4.0.x/layout/Button.lzx. La Figura 11 muestra el resultado generado.

Figura 11. Lienzo con botón
Lienzo con botón

Cómo trabajar con las disposiciones

Layout Manager le permite disponer los componentes en un contendor. La clase LzLayout es una subclase de LzNode, que es responsable de la disposición de las vistas. La clase LzLayout es la clase base que brinda esta funcionalidad. Usted nunca ejemplificará esta clase directamente, sino que siempre creará una instancia de su subclase. Las subclases de LzLayout se muestran a continuación.

SimpleLayout

SimpleLayout se usa para ubicar los componentes uno al lado del otro, de manera tanto horizontal como vertical. Se crea una instancia usando la etiqueta simplelayout, como se muestra a continuación.

Listado 10. SimpleLayout.lzx
<canvas width="450"
bgcolor="#6699FF" height="200"> <simplelayout axis="x"
spacing="4"/> <view align="center" valign="middle" bgcolor="silver"
width="100" height="100"/> <view align="center" valign="middle"
bgcolor="gray" width="100" height="100"/> <view align="center"
valign="middle" bgcolor="blue" width="100" height="100"/>
</canvas>

Invoque la muestra con http://localhost:8080/lps-4.0.x/layout/SimpleLayout.lzx. La Figura 12 muestra el resultado generado.

Figura 12. Disposición simple
Disposición simple

ResizeLayout

ResizeLayoutes similar a SimpleLayout en que le permite posicionar las vistas horizontal o verticalmente. Sin embargo, con ResizeLayout usted puede también redimensionar las vistas que se gestionan como lo muestra el Listado 11.

Listado 11. ResizeLayout.lzx
<width="450" bgcolor="#6699FF"
height="200"> <resizelayout axis="y" spacing="20"/>
<view valign="middle" width="100" height="100" bgcolor="silver"/>
<view valign="middle" width="100" height="100" bgcolor="gray"/>
<view valign="middle" width="100" height="100" bgcolor="blue"
options="releasetolayout"/> </canvas>

La aplicación anterior se puede invocar con http://localhost:8080/lps-4.0.x/layout/ResizeLayout.lzx. La Figura 13 muestra el resultado generado.

Figura 13. Redimensionamiento de la disposición
Redimensionamiento de la disposición

SimpleBoundsLayout

SimpleBoundsLayout posiciona las vistas de manera horizontal o vertical, al igual que SimpleLayout. Sin embargo, SimpleBoundsLayout se asegura de que no haya ninguna vista que se superponga con otra cuando cambian de posición. A continuación, se muestra un ejemplo en el Listado 12.

Listado 12. SimpleBoundsLayout.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <simpleboundslayout axis="x"/> <view
valign="middle" width="100" height="100" bgcolor="silver"/> <view
valign="middle" width="100" height="100" bgcolor="gray" rotation="30"/>
<view valign="middle" width="100" height="100" bgcolor="blue"/>
</canvas>

Esta aplicación se puede invocar con http://localhost:8080/lps-4.0.x/layout/SimpleBoundsLayout.lzx. La Figura 14 muestra el resultado generado.

Figura 14.SimpleBoundsLayout
SimpleBoundsLayout

ReverseLayout

Con ReverseLayout, las vistas se disponen de derecha a izquierda (a lo largo del eje x) o de la parte inferior a la superior (a lo largo del eje y). El Listado 13 muestra una aplicación LZX que usa.

Listado 13. ReverseLayout.lzx
<canvas width="450"
bgcolor="#6699FF" height="200"> <reverselayout axis="x" end="false"
spacing="20"/> <view align="center" valign="middle" width="100"
bgcolor="silver"/> <view align="center" valign="middle" width="100"
bgcolor="gray"/> <view align="center" valign="middle" width="100"
bgcolor="blue"/> </canvas>

Ejecute el ejemplo con http://localhost:8080/lps-4.0.x/layout/ReverseLayout.lzx. La Figura 15 muestra el resultado generado.

Figura 15. Disposición inversa
Disposición inversa

ConstantLayout

Esta disposición ubica las vistas una sobre otra. Al igual que con SimpleLayout, usted especifica el atributo del eje. Luego, ContantLayout desplaza cada una de las vistas la cantidad de pixeles especificada en los valores xoffset y yoffset. Como resultado se obtiene una cascada de las vistas ajustadas con estos valores.

Listado 14. ConstantLayout.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <constantlayout axis="x" value="10"/>
<view valign="middle" width="300" height="150" bgcolor="silver"/>
<view valign="middle" width="200" height="80" bgcolor="gray"
xoffset="-15"/> <view valign="middle" width="40" height="40"
bgcolor="blue" xoffset="-50"/> </canvas>

La aplicación anterior se puede invocar con http://localhost:8080/lps-4.0.x/layout/ConstantLayout.lzx. La Figura 16 muestra el resultado generado.

Figura 16. Disposición constante
Disposición constante

WrappingLayout

WrappingLayout ajusta las vistas que gestiona cambiando líneas o columnas cuando se queda sin espacio. El Listado 15 muestra un ejemplo.

Listado 15. WrappingLayout.lzx
<canvas width="450"
bgcolor="#6699FF" height="200"> <wrappinglayout axis="x"
spacing="20"/> <view align="center" valign="middle" bgcolor="silver"
width="200" height="100"/> <view align="center" valign="middle"
bgcolor="gray" width="200" height="100"/> <view align="center"
valign="middle" bgcolor="blue" width="200" height="100"/>
</canvas>

Invoque esta aplicación con http://localhost:8080/lps-4.0.x/layout/WrappingLayout.lzx. La Figura 17 muestra el resultado generado.

Figura 17. Disposición de ajuste
Disposición de ajuste

Control de eventos

Para que los programas sean más interactivos, los objetos de OpenLaszlo pueden originar eventos como respuesta a la acción de un usuario, como por ejemplo buttonclick. Esto se hace enviando electrónicamente el evento a un controlador de eventos que contiene el código a ejecutarse cuando el objeto genera el evento. Existen diversas maneras de enviar un evento a un controlador de eventos. Una de ellas consiste en asignar el nombre del controlador de eventos al nombre del evento en la declaración de la etiqueta del objeto, como se muestra en el Listado 16. La etiqueta que se muestra a continuación crea un objeto Ventana cuyo evento onx es enviado al controlador de eventos myHandler.

Listado 16. window.lzx
<window name="win" onx="myHandler">

Otro enfoque consiste en escribir un método anidado en la declaración de la etiqueta de un objeto y asignar el controlador de eventos al atributo evento de este método. El snippet del Listado 17 envía el evento onclick de un botón al controlador de eventos dentro de sus etiquetas.

Listado 17. Window.lzx
<button> <handler name="onclick"> //
Event handler code </handler> </button>

El ejemplo del Listado 18 muestra el evento onclick emitido por un botón que se mapea a un controlador de eventos.

Listado 18. EventWiring.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <button width="200" height="80" align="center"
valign="middle">Hello Button <handler name="onclick">
setAttribute("text", "Hello Button Clicked"); setAttribute ('width', 200);
</handler> </button>
</canvas>

Usted puede ejecutar el EventWiring.lxz del ejemplo navegando a http://localhost:8080/lps-4.0.x/event/EventWiring.lzx. La Figura 18 muestra el resultado generado inicialmente y el resultado después de que el evento ha sido originado al presionar el botón.

Figura 18. Control de eventos
Control de eventos

Como alternativa, el código del controlador de eventos también podría haberse incrustado en la etiqueta del objeto, como se muestra en el Listado 19.

Listado 19. EmbeddedEventHandling.lzx
<canvas width="450"
bgcolor="#6699FF" height="200"> <button width="200" height="80"
align="center" valign="middle" onclick="setAttribute ('text', 'Hello Button
Clicked'); setAttribute ('width', 200);"> Hello Button
</button> </canvas>

Controladores de eventos globales

Los controladores de eventos globales se pueden escribir con funciones JavaScript que pueden ser llamadas desde múltiples objetos. Por ejemplo, el código del Listado 20 define la función myHandler que puede ser llamada desde cualquier punto del programa.

Listado 20. GlobalEventHandler.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <button width="200" height="80" align="center"
valign="middle" id="button1" onclick="globalHandler()"> Hello Button
</button> <script> <![CDATA[ function
globalHandler () { button1.setAttribute ("text", "Hello Button Clicked");
button1.setAttribute ('width', 200); } ]]> </script>
</canvas>

La aplicación anterior se puede compilar e invocar con http://localhost:8080/lps-4.0.x/event/GlobalEventHandler.lzx.

Cómo pasar la referencia de un objeto

En OpenLaszlo, es posible pasar la referencia de un objeto a un método, como se muestra en el Listado 21.

Listado 21. PassingObjectReference.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <simplelayout axis="x"/> <button
width="200" height="80" align="center" valign="middle" id="button1"
onclick="globalHandler (this)"> Hello Button 1 </button>
<button width="200" height="80" align="center" valign="middle" id="button2"
onclick="globalHandler (this)"> Hello Button 2 </button>
<script> <![CDATA[ function globalHandler (b) { b.setAttribute
("text", "Hello Button Clicked"); b.setAttribute ('width', 200); } ]]>
</script> </canvas>

Esta aplicación se puede compilar e invocar con http://localhost:8080/lps-4.0.x/event/PassingObjectReference.lzx.


Cómo agregar animación

Por lo general, la animación de un objeto se puede lograr modificando dinámicamente el valor de sus coordinadas x e y. La animación en OpenLaszlo resulta sencilla gracias al uso de las etiquetas animator y animatorGroup. La etiqueta animator se usa dentro de un objeto para realizar un movimiento, mientras que la etiqueta animatorGroup se usa para agrupar múltiples etiquetas animator para que realicen más de un tipo de animación. La aplicación LZX del Listado 22 muestra un botón que se mueve a lo largo de una línea horizontal..

Listado 22. SimpleAnimation.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <button width="200" height="80" align="center"
valign="middle" text="Animated Stuff"> <animator attribute="x" from
="0" to="300" duration="5000"/> </button>
</canvas>

El botón del ejemplo anterior pasa de x=0 a x=450 en 5000 milésimas de segundo. Usted puede ejecutar este ejemplo con http://localhost:8080/lps-4.0.x/animation/SimpleAnimation.lzx. La Figura 19 muestra el resultado generado.

Figura 19. Animación simple
Animación simple

Múltiples piezas de animación

Al emplear más de una etiqueta animator, usted puede mover un objeto simultáneamente en dos o más direcciones. El mismo rotará a medida que se traslada por el eje x. El Listado 23 muestra el código que usa múltiples etiquetas animator.

Listado 23. MultipleAnimation.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <view width="100" height="60" align="center"
valign="middle" resource="IBMLogo.jpg> <animator attribute="x" from
="0" to="450" duration="5000"/> <animator attribute="rotation"
to="360" duration="5000"/> </view>
</canvas>

El botón de la aplicación anterior pasa de x=0 a x=450 y rota 360 grados en 5.000 milésimas de segundo. Ejecute el ejemplo navegando a http://localhost:8080/lps-4.0.x/animation/MultipleAnimation.lzx. La Figura 20 muestra el resultado generado.

Figura 20. Animación múltiple
Animación múltiple

La animación de los ejemplos anteriores comienza a moverse en cuanto se carga la aplicación generada. Se puede hacer que comience en base a un evento como por ejemplo onClick si se configura el atributo start de la etiqueta de animator en falso y se llama al método doStart en el objeto animator. Esto se muestra en el Listado 24.

Listado 24. ManualAnimationStart.lzx
<canvas
width="450" bgcolor="#6699FF" height="200"> <button width="100"
height="60" valign="middle" text="Start Animation"
onclick="this.a.doStart()"> <animator name="a" attribute="x"
start="false" from ="0" to="450" duration="1000" motion="easein"/>
</button> </canvas>

TLa aplicación anterior se puede compilar e invocar con http://localhost:8080/lps-4.0.x/animation/ManualAnimationStart.lzx.

Cómo repetir la animación

El atributo repeat de la etiqueta animator puede configurarse para determinar cuántas veces la animación debe realizar el ciclo. Fíjelo en "Infinity" (Infinito) para hacer que la animación se repita indefinidamente. Por ejemplo, la aplicación de OpenLaszlo del Listado 25 muestra una animación que se repite tres veces.

Listado 25. RepeatAnimation.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <view width="100" height="60" align="center"
valign="middle" resource="IBMLogo.jpg> <animator attribute="rotation"
from ="0" to="360" duration="3000" repeat="3"/> </view>
</canvas>

Ejecute este ejemplo con http://localhost:8080/lps-4.0.x/animation/RepeatAnimation.lzx.

El Listado 26 muestra una vista que gira alrededor de otra vista.

Listado 26. CircularAnimation.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <view valign="middle" align="center" bgcolor="#ddddee"
width="350" height="150"/> <view width="40" height="40"
bgcolor="silver" x="${ 180 + 30 * Math.cos (angle*Math.PI/180) }" y="${ 100 + 30 *
Math.sin (angle*Math.PI/180) }"> <attribute name="angle"
value="0"/> <animator motion="linear" attribute="angle" from ="0"
to="360" duration="2000" repeat="Infinity"/> <animator motion="linear"
attribute="rotation" from ="0" to="360" duration="2000" repeat="Infinity"/>
</view> </canvas>

Usted puede ver este ejemplo con http://localhost:8080/lps-4.0.x/animation/CircularAnimation.lzx. La Figura 21 muestra el resultado generado.

Figura 21. Animación circular
Animación circular

Cómo usar animatorgroup

La etiqueta animatorgroup se puede usar para agrupar múltiples etiquetas animator. El atributo process determina de qué manera se ejecutan estas etiquetas. Fije el atributo process en "simultaneous" (simultáneo) para que todos los eventos se produzcan al mismo tiempo. Fije process en "sequential" (secuencial) para que se ejecuten uno después del otro. De manera predeterminada, el atributo process es secuencial. El Listado 27 muestra el uso de animatorGroup.

Listado 27. AnimatorGroup.lzx
<canvas
height="400"> <button width="70" text="Click here">
<animatorgroup process="sequential"> <animator attribute="x"
from ="0" to="300" duration="1000"/> <animator attribute="rotation"
from ="0" to="90" duration="1000"/> </animatorgroup>
</button> </canvas>

Cómo usar timer

Un timer (cronómetro) es un objeto que se puede fijar para que invoque a un método después de que transcurra el periodo especificado. Por ejemplo, un mensaje de alerta se puede mostrar después de diez minutos de inactividad por parte del usuario, como se muestra en el Listado 28.

Listado 28. Timer.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <alert id="alertBox" width="250">10 minutes left
for Completion!</alert> <handler name="oninit"> var
delegate = new LzDelegate (this, "showAlertBox"); lz.Timer.addTimer (delegate,
3000); </handler> <method name="showAlertBox">
alertBox.open(); </method> </canvas>

El ejemplo anterior se puede compilar e invocar con http://localhost:8080/lps-4.0.x/animation/Timer.lzx. La Figura 22 muestra el resultado generado.

Figura 22. Servicio de timer
Servicio de timer

Otro ejemplo del Listado 29 muestra un reloj digital.

Listado 29. DigitalClock.lzx
<canvas fontsize="45" width="450"
bgcolor="#6699FF" height="200"> <text id="display" width="250"
bgcolor="#ddddee" align="center" valign="middle"/> <handler
name="oninit"> lz.Timer.addTimer (new LzDelegate (this, "refreshClock"),
1000); </handler> <method name="refreshClock">
lz.Timer.addTimer (new LzDelegate (this, "refreshClock"), 1000); var now = new Date
(); var hour = now.getHours (); var minute = now.getMinutes(); var second =
now.getSeconds(); display.setText (hour + ":" + minute + ":" + second);
</method> <![CDATA[ if (n < 10) { return "0" + n; } else
{ return n; } ]]> </canvas>

Ejecute este ejemplo con http://localhost:8080/lps-4.0.x/animation/DigitalClock.lzx. La Figura 23 muestra el resultado generado.

Figura 23. Reloj digital
Reloj digital

Cómo construir componentes enriquecidos

OpenLaszlo ofrece a los usuarios un conjunto de componentes enriquecidos listo para usar para cualquiera de las aplicaciones LZX. La Figura 24 muestra la jerarquía de algunos de los componentes incorporados de OpenLaszlo.

Figura 24. Jerarquía de clases de componentes
Jerarquía de clases de componentes

Control deslizante

El Control Deslizante es un componente que permite la selección de un valor al arrastrar un botón. La clase slider (control deslizante) es la plantilla para todos los controles deslizantes. Es una clase secundaria que deriva directamente de Baseslider. La clase Baseslider, a su vez, extiende la calse Basevaluecomponent, descendiente directa de Basecomponent. El código del Listado 30 usa un control deslizante para controlar la opacidad de una vista.

Listado 30. Slider.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <slider name="s" valign="middle" align="center"
height="100" showvalue="true" width="200" value="50"/>
</canvas>

La aplicación anterior se puede compilar e invocar con http://localhost:8080/lps-4.0.x/richComponents/Slider.lzx. La Figura 25 muestra el resultado generado.

Figura 25. Componente Slider (Control deslizante)
Componente Slider (Control deslizante)

datepicker (selector de fechas)

Como su nombre lo indica, el componente datepicker le permite seleccionar fácilmente una fecha. Este componente está representado por la clase datepicker, que desciende directamente de la clase Basedatepicker. Basedatepicker es una clase abstracta y una subclase de Basecomponent. Por ejemplo, el código del Listado 31 permite al usuario seleccionar una fecha y muestra la fecha seleccionada en una etiqueta de texto.

Listado 31. Datepicker.lzx
<canvas width="450"
bgcolor="#6699FF" height="200"> <script> var today = new Date
(); var lastYear = new Date (today.getFullYear () - 1, today.getMonth (),
today.getDate ()); var nextYear = new Date (today.getFullYear () + 1, today.getMonth
(), today.getDate ()); </script> <simplelayout axis="y"
spacing="5"/> <datepicker earliestdate="${lastYear}"
selecteddate="${today}" latestdate="${nextYear}"> <handler
name="onselecteddate"> if ( this.selecteddate != null ) {
display.year.setText ( this.selecteddate.getFullYear() );
display.month.datapath.setXPath( "datepicker_strings_en:/months/month[@index='" +
this.selecteddate.getMonth() + "']/@full" ); display.date.setText (
this.selecteddate.getDate() ); } </handler>
</datepicker> <view id="display"> <text
name="month" resize="true" datapath="."/> s<text name="date"
resize="true"/> <text name="year" resize="true"/>
<simplelayout axis="x" spacing="2"/> </view>
</canvas>

Usted puede compilar e invocar el ejemplo anterior con http://localhost:8080/lps-4.0.x/richComponents/DatePicker.lzx. La Figura 26 muestra el resultado generado.

Figura 26. Selector de fechas
Selector de fechas

Barra de deslizamiento

El componente barra de deslizamiento está representado por la clase scrollbar. Esta es una subclase de Basescrollbar, que es una subclase directa de Basecomponent. El código del Listado 32 muestra una aplicación LZX que usa una barra de deslizamiento vertical y una barra de deslizamiento horizontal.

Listado 32. ScrollBar.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <view name="main" width="100" height="100"
clip="true"> <text multiline="true"> OpenLaszlo is an open
source platform invented by Laszlo Systems, a company based in San Mateo, California
for the development and deployment of rich Internet based applications.It is
released under the Open Source Initiative-certified Common Public License. One of
the greatest challenge faced by Rich Interactive Applications (RIA) developers today
is that of Browser Compatibility. Since OpenLaszlo is based on the famous Java
paradigm of write-once-run-everywhere, it ensures that applications based on
OpenLaszlo runs uniformly in various browsers in multiple operating systems.
</text> <scrollbar axis="y"/> <scrollbar
axis="x"/> </view> </canvas>

El ejemplo se puede compilar e invocar con http://localhost:8080/lps-4.0.x/richComponents/ScrollBar.lzx. La Figura 27 muestra el resultado generado.

Figura 27. Barra de deslizamiento
Barra de deslizamiento

Etiquetas y recuadro de etiqueta

Una etiqueta es una vista que contiene recuadros de etiqueta. Cada recuadro de etiqueta tiene un título y puede almacenar otros componentes. La etiqueta y los recuadros de la etiqueta constituyen una buena manera de disponer los componentes en un área pequeña, como se muestra en la Listado 33.

Listado 33. TabbedPane.lzx
<canvas width="450" bgcolor="#6699FF"
height="300"> <form inset_top="10"> <tabs
tabalign="right"> <tabpane bgcolor="silver" text="Name"
tabwidth="80"> <simplelayout axis="y"/>
<text>Customer Name</text> <edittext
name="customerName"/> <text>Email</text>
<edittext name="email"/> <radiogroup
name="customerType">
<radiobutton>Silver</radiobutton>
<radiobutton>Gold</radiobutton>
</radiogroup> <button>Submit</button>
</tabpane> <tabpane bgcolor="silver" text="Address"
tabwidth="80"> <simplelayout axis="y"/>
<text>Address</text> <edittext
name="address"/> <text>City</text>
<edittext name="city"/> <text>State</text>
<edittext name="astate"/> <text>Pin
Code</text> <edittext name="pincode"/>
</tabpane> </tabs> </form>
</canvas>

Usted puede invocar el ejemplo anterior con http://localhost:8080/lps-4.0.x/richComponents/TabbedPane.lzx. La Figura 28 muestra el resultado generado.

Figura 28. TannedPane (Recuadro etiquetado)
TannedPane (Recuadro etiquetado)

Árbol

Un árbol es un componente de OpenLaszlo que se usa para mostrar datos jerárquicos, como por ejemplo XML. La clase tree (árbol) representa un árbol y es una subclase de Basetree. Basetree es una clase secundaria de Basecomponent. El código del Listado 34 muestra cómo se construye y usa un árbol.

Listado 34. TreeView.lzx
<canvas width="450" bgcolor="#6699FF"
height="200"> <view valign="middle" align="center" width="200"
height="150"> <tree open="true" text="OpenLaszlo Article">
<tree text="Chapter 1: Overview" isleaf="true"/> <tree
open="true" text="Chapter 2: Basic Components"> <tree text="Section 1:
Slider" isleaf="true"/> <tree text="Section 2: ScrollBar"
isleaf="true"/> </tree> </tree>
</view> </canvas>

Use http://localhost:8080/lps-4.0.x/richComponents/TreeView.lzx para ejecutar el ejemplo. La Figura 29 muestra el resultado generado.

Figura 29. Vista Tree
Vista Tree

Cómo trabajar con datos XML

OpenLaszlo se puede usar para mostrar y manipular datos con XPath, un lenguaje usado para recuperar datos de un documento XML. La clase LzDataset se usa para contener los datos XML y también para recuperar datos a través de solicitudes GET o POST de HTTP. La Figura 30 muestra la jerarquía de la clase LzDataset.

Figura 30. Jerarquía de la clase LzDataset
Jerarquía de la clase LzDataset

Los datos en el conjunto de datos se pueden manipular con <datapath> y <datapointer>.

DataPath

Datapath se puede usar para acceder a los datos incluidos en el conjunto de datos con XPath como se muestra a continuación. A modo de ejemplo, el código del Listado 35 muestra cómo se usa un DataPath.

Listado 35. Cómo usar DataPath.lzx
<canvas width="600" bgcolor="#6699FF"
height="220"> <dataset name="myData" request="true" type="http"
src="data.xml"/> <grid height="100" valign="middle"
datapath="myData:/company" contentdatapath="department"> <gridcolumn
width="100"> Name <text datapath="name/text ()"/>
</gridcolumn> <gridcolumn width="100"> ID <text
datapath="id/text ()"/> </gridcolumn> <gridcolumn
width="200"> Description <text datapath="desc/text ()"/>
</gridcolumn> <gridcolumn width="100"> Location
<text datapath="location/text ()"/> </gridcolumn>
<gridcolumn width="70"> <view datapath="position ()">
<button text="delete"> <handler name="onclick">
parent.datapath.deleteNode (); </handler> </button>
</view> </gridcolumn> </grid>
</canvas>

El Listado 36 muestra los contenidos de data.xml.

Listado 36. Contenido de data.xml
<company>
<department headCount="19">
<name>HR</name>
<id>Comp-HR-01</id>
<location>First-Flr</location> <desc>Looks
after Human resources</desc> </department>
<department headCount="200">
<name>Manufacturing</name>
<id>Comp-MFG-02</id>
<location>Ground-Flr</location>
<desc>Manufactures Components</desc>
</department> <department headCount="65">
<name>Marketing</name>
<id>Comp-Mktg-01</id>
<location>Third-Flr</location>
<desc>Markets the product</desc>
</department> </company>

La aplicación anterior se puede compilar e invocar con http://localhost:8080/lps-4.0.x/data/UsingDataPath.lzx. La Figura 31 muestra el resultado generado.

Figura 31. Cómo usar Datapath
Cómo usar Datapath

DataPointer

DataPointer funciona como un cursor dentro del conjunto de datos. DataPointer se puede usar para moverse secuencialmente por los registros incluidos en el conjunto de datos. El Listado 37 muestra cómo se usa un DataPointer.

Listado 37. Cómo usar DataPointer.lzx
<canvas
width="450" bgcolor="#6699FF" height="200"> <simplelayout
spacing="5"/> <script> var isLast = false;
</script> <dataset name="mydata" request="true" type="http"
src="data.xml"/> <alert name="myalert"/> <view id="tt"
height="60" valign="middle" width="450" font="verdana" fontsize="20">
<text name="output" y="30" align="center"/> </view>
<view height="150" align="center" valign="middle" >
<simplelayout axis="x" spacing="4" /> <datapointer id="mydp"
xpath="mydata:/company/department[1]"/> <button font="verdana"
fontsize="15"> Next Record <handler name="onclick"> isFirst =
false; var s = mydp.xpathQuery('name/text()'); if(isLast){ s = 'Last Record!'; }
if(!mydp.selectNext()){ isLast = true; } tt.output.setText(s);
</handler> </button> </view>
                </canvas>

Ejecute este ejemplo con http://localhost:8080/lps-4.0.x/data/UsingDataPointer.lzx. La Figura 32 muestra el resultado generado.

Figura 32. Cómo usar DataPointer
Cómo usar DataPointer

Depuración

En el desarrollo de software, las buenas herramientas de depuración hacen que las aplicaciones sean más robustas y libres de defectos. OpenLaszlo viene equipado con una herramienta de depuración que permite a los desarrolladores visualizar mensajes de error en tiempo de ejecución, evaluar los valores de las variables, etc.

Para visualizar la ventana Debugger (Depurador), siga estos pasos:

  • Fije el atributo debug de la etiqueta del lienzo en verdadero: <canvas debug="true">
  • Anexe el parámetro de consulta debug=true el final de la URL que se usa para solicitar la aplicación de OpenLaszlo. Por ejemplo:
    http://localhost:8080/lps-4.0.x/app14/debugTest.lzx?debug=true
  • Presione sobre el botón de radio Debug y sobre el botón Compile

A modo de ejemplo, el código del Listado 38 muestra un botón en un lienzo.

Listado 38. DebugButton.lzx
<canvas width="450"
bgcolor="#6699FF" height="800"> <button id="buttonId" width="200"
height="80" align="center" valign="middle"> Hello
World!!</button> </canvas>

La aplicación anterior se puede invocar con una depuración activada al abrir su URL con el parámetro debug=true: http://localhost:8080/lps-4.0.x/debug/DebugButton.lzx?debug=true. De esta manera se cargará la aplicación y se abrirá una ventana de Laszlo Debugger con un campo de ingreso de datos en la parte inferior.

Escriba la ID del botón buttonId y presioneEnter. El texto de entrada quedará en verde, y el depurador imprimirá el objeto como un hipervínculo en azul.

A continuación, presione sobre el vínculo del objeto en la ventana del depurador <<button>#0| #buttonId>>. El depurador imprimirá los atributos del objeto de JavaScript como se muestra en la Figura 33.

Figura 33. Ventana del depurador
Ventana del depurador

Al escribir una expresión de JavaScript en el depurador, la misma se compilará y se imprimirá el resultado. Por ejemplo, buttonId.width devolverá el valor del atributo ancho. De manera similar, al ingresar el comando buttonId.setAttribute('width', 400) se modificará el ancho del botón visualizado en el lienzo. La ventana Debugger es una instancia de la clase Debug, que es una subclase de LzView. Por lo tanto, todos los atributos de la clase LzView también se encuentran disponibles en la clase Debug.

A continuación presentamos los métodos definidos en la clase Debug:

  • backtrace (frameCount)— Copie la instantánea de la pila actual de llamadas a un objeto LzBacktrace, que luego se podrá imprimir o inspeccionar. Este método sólo está disponible si la aplicación está compilada con -option debugBacktrace=true. El argumento frameCount especifica la cantidad de marcos que se deberán omitir del backtrace. (el valor predeterminado es 1).
  • error (control, args)— Muestra un error en la consola. El argumento control especifica un control de formato y el argumento args representa cualquier número de argumentos.
  • format (control, args)—Formatea el resultado usando el método formatToString. El argumento control especifica un control de formato y el argumento args representa cualquier número de argumentos.
  • formatToString (control, args)— Este método es similar a la función printf del lenguaje C. El argumento control especifica un control de formato y el argumento args representa cualquier número de argumentos.
  • inspect (object, reserved)— Muestra las propiedades del objeto especificado en la consola de depuración. El argumento reserved se reserve para un uso posterior.
  • log (message)— Envía un mensaje al archivo de registros.
  • monitor (object, property)— Monitorea la propiedad especificada del objeto especificado. Cada vez que cambia el valor de la propiedad, se visualizará un mensaje en la ventana Debugger.
  • trace (object, method)— Monitorea el uso del método especificado en el objeto especificado. Cada vez que se invoca el método, se imprime un mensaje en la ventana Debugger.
  • unmonitor (object, property)— Cancela el monitoreo de la propiedad especificada en el objeto especificado.
  • untrace (object, method)— Cancela el monitoreo del monitor especificado en el objeto especificado.

La ventana Debugger también se puede usar para evaluar las variables y expresiones globales de JavaScript, y para ejecutar los enunciados de JavaScript. El evaluador se encuentra en el campo de texto y el botón EVAL en la parte inferior de la ventana Debugger.


Conclusión

OpenLaszlo es una plataforma de desarrollo de código abierto para construir aplicaciones Web enriquecidas escritas en LZX, que es un lenguaje XML que incluye JavaScript incrustado.

A diferencia de muchas soluciones de Ajax, sin embargo, las aplicaciones de OpenLaszlo se pueden transportar a distintos navegadores. Esto es posible gracias a la tecnología de compilación de OpenLaszlo, que cuida los detalles del tiempo de ejecución, permitiendo que el desarrollador se concentre más en el comportamiento/ la lógica y la apariencia de la aplicación, conformando así una verdadera plataforma de “escriba una vez y ejecute en todos lados”. OpenLaszlo soporta un modelo de gráficos enriquecidos con numerosos componentes incorporados y reutilizables, así como texto WYSIWYG avanzado y herramientas de edición gráfica.


Descargar

DescripciónNombretamaño
Sample OpenLaszlo Code for this articleos-openlaszlo-ArticleCode.zip12KB

Recursos

Aprender

Obtener los productos y tecnologías

Comentar

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=WebSphere
ArticleID=481994
ArticleTitle=OpenLaszlo: Una plataforma para construir e implementar rápidamente aplicaciones de Internet enriquecidas
publish-date=07292011