ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


Exploring Laszlo Classes, Attributes, and Events

by Satya Komatineni
06/15/2005

Laszlo, an XML platform for rich internet applications, recently went open source. This platform applies an architecture that is similar to XUL and XAML to accomplish programming on the browser side. Laszlo uses Macromedia Flash as its execution platform, resulting in unsurpassed browser compatibility without requiring Macromedia Flash executables or licensing for development.

Laszlo applications are written in LZX. LZX is an XML-based programming language that can be written using any text editor. When these files are accessed through a Laszlo servlet, Laszlo compiles these LZX files into byte codes or binary format, which are then sent to the Macromedia Flash plugin in your browser. No Macromedia Flash components are needed on your server side. The Macromedia Flash plugin is widely available and compatible with most browsers.

You can read the basics of this platform in an article titled "Laszlo: An Open Source Framework for Rich Internet Applications," by Bill Grosso at Java.net. In this article, I will focus on some of the language fundamentals that will come in handy as you start writing your own programs using LZX. For in-depth study, refer to the documentation on the Laszlo site.

Setting Up your Experimental Laszlo "Developer Pad"

Use my notes on Laszlo, or the Laszlo website, to download and install Laszlo. It is possible you may already have a prior installation of Tomcat. If so, Laszlo's installation documentation advises stopping Tomcat while installing Laszlo. If you don't already have it, Laszlo comes with a copy of Tomcat. Once installed, you can use my notes above to set Laszlo as another web app in your installation of Tomcat. For an experienced Tomcat user, this is just a matter of setting the web app root.

Let me start the discussion by creating a small LZX file to start your development process. This file looks like the following:


<canvas height="500" width="800" debug="true">
        <debug x="450" y="0" height="300"/>
</canvas>

When this LZX file is accessed through a browser, you will see the layout in Figure 1 in your browser. I call this your "developer pad." This will be the starting point for your application needs. This initial set up allows you to write debug statements and have them displayed in the debug window. This setup also allows you enough space outside of the debugger for placing the visual controls.

The Laszlo 'Developer Pad'
Figure 1. The Laszlo "Developer Pad"

Writing a Class

Now that you have a workable development pad, you can start the coding exercise by writing a class in Laszlo. The fundamental aspect of a class is its set of local variables. The following code defines a class and a couple of variables for that class. If not for the XML syntax, the class definition in Laszlo would be quite close to a class definition in Java. Unlike Java, Laszlo's type system is closer to that of a dynamic language like JavaScript; that is to say, it is flexible, or loose.


<canvas width="800" debug="true">
<debug x="450" y="0" height="300"/>

<class name="test">
        <attribute name="a1" type="string"/>
        <attribute name="b1"/>
</class>

</canvas>

In Laszlo, everything happens inside of the <canvas> tag. As this example shows, an LZX class is defined inside of a <canvas> tag. This code defines a class named test and two attributes, a1 and b1.

Instantiating a Class

With the above class definition in place, the following code shows how to instantiate the defined class test:


<canvas width="800" debug="true">
<debug x="450" y="0" height="300"/>

<class name="test">
        <attribute name="a1" type="string"/>
        <attribute name="b1"/>
</class>

<!--Instantiating a class-->
<test name="testInstance">
</test>

</canvas>

Look at how the class name test becomes a subsequent node or <test> tag for instantiation. The instantiated object is named testInstance and is available as the variable canvas.testInstance where needed.

The Nature of Attributes in Laszlo

In Laszlo, every time an attribute is set or changed, an onchange event is generated for that attribute. This is pretty nice for visual programming, where things are controlled by events. Making this a language construct saves a lot of coding, not to mention the increase in readability and understanding.

Since the main focus of this article is to show you how attributes are set, events fired, and code written in response to those events, let me show you how one could write an onchange event for one of the attributes, a1.


<canvas width="800" debug="true">
<debug x="450" y="0" height="300"/>

<class name="test">
        <attribute name="a1" type="string"/>
        <attribute name="b1"/>
</class>
<!--Instantiating a class-->
<test name="testInstance">

        <!--Demonstrating an onchange for attribute event-->
        <method event="ona1" name="ona1Method">
                Debug.write("hey this works");
        </method>
      
</test>
</canvas>

See how a method is defined for the ona1 event? This event is fired when changes are made to the attribute a1. This code also shows you the basic syntax for defining a method. Also notice that, unlike Java, this method belongs to the object or the instance, and is not available in the class. The method body here writes a line to the debugger. As the debugger is already enabled, this line will show up in the debugger window.

While writing LZX, notice that all of the LZX constructs and naming are case-insensitive. Nevertheless, while defining the nodes and tags in XML, XML is still case-sensitive; so is JavaScript. So bear this distinction in mind as you proceed with Laszlo.

Refining the "Developer Pad" with Alerts

While programming in JavaScript, it is common to debug using alert(). So I searched for the trusted alert() in Laszlo--to no avail. But I did come across a control (a modal dialog, to be precise) called alert. I figured I could use this control to debug by simulating an alert function. What follows is a first attempt. In addition, this code exercises the basic features of LZX I have talked about so far.


<canvas width="800" debug="true">
<debug x="450" y="0" height="300"/>
<class name="test">
        <attribute name="a1" type="string"/>
        <attribute name="b1"/>
</class>
<!--Instantiating a class-->
<test name="testInstance">
        <!--Demonstrating an onchange for attribute event-->
        <method event="ona1" name="ona1Method">
                Debug.write("hey this works");
        </method>
</test>

<!-- Simulating an alert -->
<!-- Instantiate a modal alert dialog -->
<alert name="myalert" width="100" y="100">
   hi - initial text
</alert>

<!-- A method to work the modal dialog -->
<method name="showAlert" args="displayText">
   canvas.myalert.setAttribute("text",displayText);
   canvas.myalert.open();
</method>

<!-- Testing the alert function -->
<button onclick="canvas.showAlert('Alert Button Pressed')">
    Show Alert
</button>

</canvas>

In the code above, I created the alert component instance as a child of the canvas, and provided the alert with coordinates and size. I also named the component myalert and gave it a body: "hi - initial text."

I also wrote a method called showAlert to show the dialog. This method has an argument named text. The body of the method accesses the modal dialog and sets its attribute text to the displayText. Subsequently, the method does an open on the modal dialog.

I also created a button to call showAlert(). When this showAlert button is pressed, you will see an alert dialog with your text. Because this button is a child of the canvas and has no positioning set, it will show up at the top left corner of the canvas. You can change the button positioning by placing it underneath the debug window using the following code:


<button x="500" y="310" 
        onclick="canvas.respondToMethod()">
Show Alert
</button>

You can see the result in Figure 2.

The Laszlo 'developer pad' with an alert
Figure 2. The Laszlo "developer pad" with an alert window

Exploring the Linkage Between Attributes and Events

The sample code now has the necessary tool set to explore the linkage between attributes and events a bit further. The button that was used to test the alert can also be used to set the attributes that I have defined earlier. I want to show how setting those attributes will fire the corresponding onchange methods.

What follows is a method, respondToButton(), that will be called when the showAlert button is clicked.


<canvas width="800" debug="true">
<debug x="450" y="0" height="300"/>
<class name="test">
        <attribute name="a1" type="string"/>
        <attribute name="b1"/>
</class>
<!--Instantiating a class-->
<test name="testInstance">
        <!--Demonstrating an onchange for attribute event-->
      
        <method event="ona1" name="ona1Method">
                Debug.write("hey this works");
        </method>
      
</test>

<!-- Simulating an alert -->
<!-- A modal alert dialog -->
<alert name="myalert" width="100" y="100">
   hi - initial text
</alert>

<!-- A method to work the modal dialog -->
<method name="showAlert" args="displayText">
   canvas.myalert.setAttribute("text",displayText);
   canvas.myalert.open();
</method>

<!-- Testing the alert function -->
<button onclick="canvas.respondToButton()">Show Alert</button>
<method name="respondToButton" >
        //Prepare a string
        var somestring =
                "Hey, I am setting the a1 attributes value";

        //Write a debug to see it
        Debug.write(somestring);

        //Call the alert to see it
        showAlert(somestring);

        //Go ahead and set the attribute
        canvas.testInstance.setAttribute("a1",'satya');
        //The above will fire an event causing
        //"ona1Method" to execute.
        //You will see this in the debugger
</method>

</canvas>

Notice how the button click sets the attribute of the testInstance object that is declared using its class test. One common mistake while writing an LZX method is to put braces after a method's name; you don't need them.

When you run this example, clicking the button brings up the alert seen in Figure 1.

Event-firing example
Figure 3. Event-firing example

Using a Script Instead of a Method

Laszlo also allows a <script> tag to define functions and other procedural logic. To show this, let me modify the code above to include some scripting and briefly note the characteristics of an LZX script.


<canvas width="800" debug="true">
<debug x="450" y="0" height="300"/>

<!-- The previous respond method -->
<method name="respondToButton" >
        //Prepare a string
        var somestring = 
            "Hey, I am setting the a1 attributes value";
        //Write a debug to see it
        Debug.write(somestring);

        //Call the alert to see it
        showAlert(somestring);

        //Go ahead and set the attribute
        canvas.testInstance.setAttribute("a1",'satya');

        //The above will fire an event causing
        //"ona1Method" to execute.
        //You will see this in the debugger
</method>

<!-- Your method rewritten as a script -->
<script>
function respondToButtonUsingScript()
{
        var somestring = 
            "Hey, I am setting the a1 attributes value";
        Debug.write(somestring);
        showAlert(somestring);
        canvas.testInstance.setAttribute("a1",'satya');
}
</script> 
<!-- Button now calling the global script function -->
<button onclick="respondToButtonUsingScript()">
    Show Alert
</button>


<class name="test">
        <attribute name="a1" type="string"/>
        <attribute name="b1"/>
</class>
<!--Instantiating a class-->
<test name="testInstance">
        <!--Demonstrating an onchange for attribute event-->
        <method event="ona1" name="ona1Method">
                Debug.write("hey this works");
        </method>
</test>
<!-- Simulating an alert -->
<!-- A modal alert dialog -->
<alert name="myalert" width="100" y="100">
   hi - initial text
</alert>
<!-- A method to work the modal dialog -->
<method name="showAlert" args="displayText">
   canvas.myalert.setAttribute("text",displayText);
   canvas.myalert.open();
</method>
</canvas>

Laszlo's script is similar to JavaScript and follows similar, if not the same, conventions. In Laszlo, a script tag is allowed only inside of the root canvas object and nowhere else. Any code inside of the script, unless it is a function, is executed immediately. That means that a script tag can include code that is not inside of any function. I tend to call this sort of code an "inline code segment."

Needless to say, a script tag can contain function definitions. These functions are considered global. In contrast, an LZX's methods belong to the respective nodes under which they are defined. For instance, a method that is defined using a method tag inside of the root canvas belongs to the canvas object and is scoped and named accordingly.

Inside of a script, you can use Java-style (//) line comments. Because the script tag is inside of another XML tag, it is sometimes necessary to include the body of the script in a CDATA section to avoid conflict with any < or > characters.

Just like in JavaScript, if a variable is declared without a var, then that variable is considered global. It is better to declare variables with a var scope.

Related Reading

Java and XML
Solutions to Real-World Problems
By Brett McLaughlin

Where to Go from Here

What I have covered so far about Laszlo falls under language fundamentals. LZX is a fusion of three language concepts: XML, OO programming, and JavaScript. You will need to spend some time with LZX to know how these three concepts are melded together, especially in the use of instance methods. Also, in JavaScript, the terms object, dictionary, and array can be used synonymously: this idea is used more extensively in LZX. You will need to brush up on these concepts of JavaScript one more time to develop successfully in Laszlo.

I also have touched briefly on Laszlo's visual programming model, involving components and events. Obviously, there is a lot more to the visual programming side if you want to do practical programs. In particular, you will need to master the various visual components that come with Laszlo. For example, you'll find a grid control and a tree control among the list of components that you can use to build your applications.

One area I haven't even touched in this article is the data handling side of Laszlo. It uses data binding and XML navigation extensively. Briefly, Laszlo uses URLs to retrieve XML data sets that are bound to visual controls. The relationship between the UI and the data is lot closer. Data affects the UI much more substantially in Laszlo. For example, a UI component bound to an XML node that has siblings will get replicated (if needed).

Conclusion

This introductory article gave you a starting point for experimenting with Laszlo and starting to explore it. The Laszlo documentation links in the Resources section of this article are a good place to start reading more about the language elements. I also keep running notes on Laszlo as I experiment with it, and keep Laszlo sample code on my weblogging system "akc."

Resources

Satya Komatineni is the CTO at Indent, Inc. and the author of Aspire, an open source web development RAD tool for J2EE/XML.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.