Table of Contents
LZX is an object-oriented, prototype-based language that allows you to create custom, reusable classes to streamline and minimize code.
This tutorial shows you how to define and instantiate classes, as well as where to use them.
The <class>
tag is used to define classes. Classes are instantiated when the tag is used.
Example 12.1. Simple Class Example
<canvas
width
="100%
" height
="80
">
<class
name
="MyClass
" width
="80
" height
="25
" bgcolor
="#CFD9AB
">
<text
align
="center
" valign
="middle
">Hello, World!
</text
>
</class
>
<MyClass
name
="myFirstInstance
"/>
</canvas
>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* X_LZ_COPYRIGHT_END ****************************************************** -->
The <class>
tag defined the class, and the <MyClass>
tag instantiated it.
Everything that was in the definition of the class is inherited by each instance of it that is created.
That is, the instance of MyClass inherits a width of 80, a height of 25, a background color, as well as some text.
The instance is named "myFirstInstance", in the same way we might name a <view>
, or
a <window>
.
In fact, when we write <window>
, we are actually instantiating the window class,
which is a pre-defined class.
In this example, there is only one element within the class (the <text>
element). But classes can contain many objects;
for example, views can contain many subviews.
It's important to note that you should not assign an id
attribute
in a class definition. Each id should be unique; ids are global and if you were to include an id assignment in the class
definition, then creating several instances of a class would several views with the same id, which would cause unpredictable
behavior.
As mentioned above, instances of <MyClass>
are going to inherit from it. Just because we
didn't specify x
and y
coordinates in the class definition doesn't mean we can't give them to the instance:
The <class>
tag defined the class, and the <MyClass>
tag instantiated it. Everything that was in the definition of the class is inherited by the instance of it that we have created. i.e. The instance of <MyClass>
inherits a width of 80, a height of 25, a background color, as well as some text. The instance is named "myFirstInstance",
in the same way we might name a view, or a <window>
.
The instances behave just like views. In fact, that's because we are extending the view class. By default, the <class>
tag extends the view class, so:
<class name="MyClass">
… is the same as…
<class name="MyClass" extends="view">
It follows that you can extend any class you want:
Example 12.2. Extending the 'button' class
<canvas
width
="100%
" height
="80
">
<class
name
="SpecialButton
" extends
="button
" onclick
="changeLabel()
">
<method
name
="changeLabel
">
this.setAttribute('text', 'Clicked! ');
</method
>
</class
>
<SpecialButton
>Not clicked
</SpecialButton
>
</canvas
>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* X_LZ_COPYRIGHT_END ****************************************************** -->
Since the <button>
can take a text childnode that becomes its label, the <SpecialButton>
class
that extends it can also take the text childnode. The method changeLabel()
is also inherited by the instance.
Just as with attributes, methods can be overridden in instances:
Example 12.3. Overwriting methods
<canvas
width
="100%
" height
="80
">
<class
name
="SpecialButton
" extends
="button
" onclick
="changeLabel()
">
<method
name
="changeLabel
">
this.setAttribute('text', 'Clicked!');
</method
>
</class
>
<simplelayout
axis
="y
" spacing
="10
"/>
<SpecialButton
>Not clicked
</SpecialButton
>
<SpecialButton
>
Click Me Now
<method
name
="changeLabel
">
this.setAttribute('text', 'Smashing!');
</method
>
</SpecialButton
>
</canvas
>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2007, 2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* X_LZ_COPYRIGHT_END ****************************************************** -->
Rewriting methods can be very handy when using both your own and pre-defined classes components, but it's not practical for when you have a class for which every instance may need a particular argument.
We've used attributes before (e.g. width="160"), but these have been attributes that are present in the class we are extending. As mentioned above, it is useful to be able to pass an instance of a class an argument when it is created:
Example 12.4. Passing an argument to a class instance
<canvas
width
="100%
" height
="80
">
<class
name
="SpecialButton
" extends
="button
" onclick
="changeLabel()
">
<attribute
name
="changeToLabel
" value
="Clicked!
" type
="string
"/>
<method
name
="changeLabel
">
var newLabel = this.changeToLabel;
this.setAttribute('text', newLabel);
</method
>
</class
>
<simplelayout
axis
="y
" spacing
="10
"/>
<SpecialButton
>Not clicked
</SpecialButton
>
<SpecialButton
changeToLabel
="Thank You!
">Please click me!
</SpecialButton
>
</canvas
>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* X_LZ_COPYRIGHT_END ****************************************************** -->
If we give the attribute a value, then that will be its default value, and will get assigned if we don't explicitly set it.
You can extend a class more than once. For example, an application might contain more than one kind of button:
A standard button that is blue, then switches to green when we roll over it. Clicking this button writes out the name of a pet.
A special button, that is red, but also switches to green when we roll over it. Clicking this button writes out a day of the week.
Example 12.5. Extending a class more than once
<canvas
width
="100%
" height
="180
">
<resource
name
="standardButton
">
<frame
src
="resources/button_blue.gif
"/>
<frame
src
="resources/button_green.gif
"/>
</resource
>
<resource
name
="specialButton
">
<frame
src
="resources/button_red.gif
"/>
<frame
src
="resources/button_green.gif
"/>
</resource
>
<class
name
="MyButton
" resource
="standardButton
" onclick
="doAction()
" onmouseover
="doOver()
" onmouseout
="doOut()
">
<method
name
="doAction
"> pet.addText("dog ");
</method
>
<method
name
="doOver
"> this.setAttribute('frame', 2);
</method
>
<method
name
="doOut
"> this.setAttribute('frame', 1);
</method
>
</class
>
<class
name
="MySpecialButton
" extends
="MyButton
" resource
="specialButton
">
<method
name
="doAction
"> weekday.addText("Monday ");
</method
>
</class
>
<view
name
="buttons
" x
="5
" y
="5
">
<simplelayout
axis
="y
" spacing
="10
"/>
<MyButton
/>
<text
id
="pet
"/>
<MySpecialButton
/>
<text
id
="weekday
"/>
</view
>
</canvas
>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2008 Laszlo Systems, Inc. All Rights Reserved. *
* Use is subject to license terms. *
* X_LZ_COPYRIGHT_END ****************************************************** -->
Here we only changed the doAction()
method and the resource. The doOver()
and doOut()
methods remained the same, so there was no need to redefine them in the MySpecialButton definition.
Since we frequently write classes that extend view, at some stage we're going to need to place a view inside an instance of
a class that we have created. For example, we may want to write a window class and put a text field inside of its title bar.
Or we may want to put some content inside the middle of our window. There are two ways to do this: giving the subviews placement
attributes, or giving the class the defaultplacement
attribute.
If you had one view and you specifically wanted to place it in a particular subview of a class, you would use the placement
attribute of that view.
An example is the title bar of a window: It's unlikely that you would need to place several things in the title bar of a window,
so it's OK to have to add the placement
attribute to the subview of the class that you want to place in the title bar.
If you want every subview of a class to be placed in the same location, then you give the class definition a defaultplacement attribute.
An example is the contents of a window class. If you built your own window class (see the window tutorial), you might well have an area for all window content. You might well place numerous subviews in that window, and you don't want to explicitly position each one.
Copyright © 2002-2010 Laszlo Systems, Inc. All Rights Reserved. Unauthorized use, duplication or distribution is strictly prohibited. This is the proprietary information of Laszlo Systems, Inc. Use is subject to license terms.