Any decent abstraction layer will try to solve as many details for you as possible. We have tried to make the presentation layer of jZeno easy to use and take away details such as JavaScript/CSS/HTML/DOM/etc... At the same time we recognise that there will allways be situations where you want to take full control over these details (i.e. bypass the abstraction layer). Therefore It should be extremely simple to bypass the regular rendering model. This section explains how you can create a type of custom component that has full control over rendering.
We also think the class of applications we are targeting with jZeno only have a small number of cases where this is necessary.
In this example we'll create a component that allows an external web site to be visualized inside of a jZeno application. The HTML required to do this is extremely simple, we simple need to create an IFRAME. The example has been kept simple for didactical reasons, but you can readily imagine how this component could have more properties in a more realistic version. Basically you need to derive your component from CustomRenderingComponent.
package howto.bypass; import net.sj.jzeno.echo.component.CustomRenderingComponent; public class ExternalSiteViewer extends CustomRenderingComponent { private String url = "http://www.google.com"; // We still need the 2 required constructors for dynamic components. public ExternalSiteViewer() { this(null,null,null); } public ExternalSiteViewer(Class beanClass, String propertyPath, String constructionHints) { super(beanClass, propertyPath, ""); EchoSupport.executeHints(this, constructionHints); } public void setUrl(String url) { String oldUrl = this.url; this.url = url; firePropertyChange("url", oldUrl, url); } public String getUrl() { return url; } // Here you get to render your component into HTML. String getHtml() { return "<iframe src=\"" + getUrl() + "\" width=\"800\" height=\"600\" frameborder=\"0\"/>"; } String getJavascript() { return null; } String getJavascriptLibrary() { return null; } void update(String input) {} }
In the example we implement 4 important functions :
It also imprtant to take a look at the setUrl() method. Specifically you need to add a similar firePropertyChange event to all of the properties that change the client side rendered component. The propertyChange event is detected by jZeno and is used to enlist your component to be re-rendered.
In order to send state updates from the client browser back to the server you need to do 2 things :
package howto.bypass; import net.sj.jzeno.echo.component.CustomRenderingComponent; public class MyButton extends CustomRenderingComponent { public MyButton() { this(null,null,null); } public MyButton(Class beanClass, String propertyPath, String constructionHints) { super(beanClass, propertyPath, ""); EchoSupport.executeHints(this, constructionHints); } String getHtml() { return "<input type=\"button\" onclick=\"" + createUpdateScript("'action'",true) + "\" />"; } void update(String input) { if(input.equalsIgnoreCase("action")) { fireActionEvent(); } } String getJavascript() { return null; } String getJavascriptLibrary() { return null; } }