Macro Components, Window “use” clause, and POJO’s

From Documentation
DocumentationSmall Talks2007FebruaryMacro Components, Window “use” clause, and POJO’s
Macro Components, Window “use” clause, and POJO’s

Author
Andrew SanClemente, Senior Software Architect, DigiHome (Massachusetts, USA).
Date
February 1, 2007
Version
Applicable to ZK 2.0 and later.


Introduction

The how-to on using macro components is covered quite well in the ZK Development Guide as is the use of Java files to replace the default ZK component classes. What is not covered is exactly how you can get a handle to the macro component inside of a java file that has extended a zk component. We also have just a few more simple examples of utilizing these tools in a sample ZK app which in of itself can sometimes prove helpful.


Example Files

In the following example you would have the following .zul files defined :

  • /test/samples/tuner.zul A very simple zul file used to define a macro component.
  • /test/samples/mainwindow.zul The main window illustrating the use of macro components.


tuner.zul
<window componentname="/dhumainwindow/tunerwindow" use="com.foo.test.TunerSample">
  <label id=”samplelabel” value=”Sample Label”/>
</window>


mainwindow.zul
<?component name="tunerwindow" macro-uri="/test/samples/tuner.zul"?>

<window id="dhumainwindow" use="com.foo.test.MainWindow" border="normal">
  <tunerwindow id="sampletunerwindow"/>
  <hbox>
	<button label="Volume" id="samplebutton"
	  onClick="dhumainwindow.sampleButtonClickHandler();"/>
  </hbox>
</window>


In additions, two Java files located in the example package, com.foo.test :

  • MainWindow.java which contains the class MainWindow which extends the zk Window class.
  • TunerSample.java which contains the TunerSample class which extends the zk Window class.


Looking at the mainwindow.zul file, at the top we have defined a macro component that defines the name of the macro component as tunerwindow and specifies the definition of that component is in /test/samples/tuner.zul – which in this case happens to be another zk window which could hold anything a zk window is capable of holding. Once we have defined the component we then can incorporate it into our main window with the lines :

<?component name="tunerwindow" macro-uri="/test/samples/tuner.zul"?>

And in the body of the window :

<tunerwindow id="sampletunerwindow"/>


Again, this is all covered in the manual, for the sake of understanding how to tie this into a Java POJO, pay attention to the following :

1. use="com.foo.test.MainWindow" This is saying that when this .zul window is created, it is to be coupled with the java file located in the package com.foo.test and named MainWindow.java which extends the ZK Window class.
2. <button label="Volume" id="samplebutton" onClick="dhumainwindow.sampleButtonClickHandler();"/> By using the id of the window that has been specified in the window declaration dhumainwindo we can then tell ZK to call the method sampleButtonClickHandler on the class specified in the use clause – com.foo.test.MainWindow which would live in the Java File com.foo.test.MainWindow.java.


The Java File

Now we need to code the java class that we have defined in our zul file as com.foo.test.MainWindow. First we must extend the ZK Window class :

package com.foo.test;

public class MainWindow extends Window
{
	. . .
Important Note :
To ensure you have a link between the .zul window definition and the Java definition make sure you have the package and java class name correct in the use clause inside of the .zul file.

At this point in a real application you will most likely need a handle or reference to the macro-component we defined called tunerwindow. We would get the reference to this component in the onCreate method on the Window class. The following code demonstrates how to do this :

public void onCreate()
{

 HtmlMacroComponent tunerMacro =
   (HtmlMacroComponent)Path.getComponent("/dhumainwindow/tunerwindow");

  // In the on create you can get a handle also to buttons, images, any ZK compoment
  // For example to get the sample button :

 Button sampleButton = (Button)Path.getComponent("/dhumainwindow/samplebutton");

 . . .
}

This gets us a reference to the macro but that is not what we want, we want a reference to the Window we had defined in /test/samples/tuner.zul and more importantly the Java Class that was specified in the tuner.zul use clause. To do this we need to use the following code :

Window tunerSampleWindow = (Window)tunerMacro.getChildren().get(0);

Now in most situations we would have coded a Java Class to represent the tuner Window. For this example would TunerSample.java and the class TunerSample would extend the Window class. Assume this class also resides in the com.foo.test package and then the line of code above would look like the following :

// Cast the window to the Java type we have created to extend the Window Class
TunerSample tunerSampleWindow = (TunerSample)tunerMacro.getChildren().get(0);
// We could then store a handle to this window for later access
setTunerSampleWindow(tunerSampleWindow);


At this point you would have access to not only all of the attributes and methods of the ZK window class which the TunerSample class extends, but any methods you may choose to add onto the class as well.

An example of using a macro in this manner is a main window class which handles high-level navigation say via icons at the top of the screen, and depending upon which icon is selected you are setting a sub-window (like the TunerSample) visible or not visible. You need to have a reference in the MainWindow java class to the macro component to allow you to do this.

We could use the onClick="dhumainwindow.sampleButtonClickHandler();" for just such an operation. On the MainWindow class we would specify a method called sampleButtonClickHandler() as follows :

// This method is called when the user clicks on the sampleButton on the main window
public void sampleButtonClickHandler()
{
     // up above we saved the handle to this window in the MainWindow onCreate method
     // we just retrieve it here
     TunerSample tunerSampleWindow = getTunerSampleWindow();
     // Hide the tunerSampleWindow
     tunerSampleWindow.setVisible(false);
}


At this point you have created and used a macro-component in a .zul file, then defined java classes for both the macro component and the main window that the component is used in. We then retrieved a reference to the macro component in the java file for the main window, and used a button callback to make the macro-window no longer visible. This is a very rudimentary example but should aid somewhat in putting together how you utilize macros with POJO’s.


Ruler.gif


Andrew SanClemente a Senior Software Architect for a startup company called DigiHome involved in the Home Automation space. I am involved in overall design of the system as well as the actual implementation. We are utilizing ZK, Java, JBoss, MySQL, and the Java Persistence API in our application.




Copyright © Andrew SanClemente. This article is licensed under GNU Free Documentation License.