0

A native component library corresponding to the core components

asked 2011-11-11 03:24:11 +0800

RichardL gravatar image RichardL
768 4

updated 2011-11-11 03:28:24 +0800

I've just started doing some performance tuning using HtmlNativeComponent and am wondering why there aren't any native components that correspond to ZK's standard components. I think this would lead to more intuitive development and refactoring for the developer. Instead of dealing with namespaces, a native component, such as div, could be just:

<nativediv width="150px">My content</nativediv>

In Java, I have developed some of my own wrappers to mimic the layout of the standard ZK components. Here is my NativeHlayout class:

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlNativeComponent;

/**
 *
 * @author Richard Lovell
 */
public class NativeHlayout extends HtmlNativeComponent {
    
    public NativeHlayout(){
        this.setTag("div");
        this.setEpilogContent("<div style=\"clear:both;\"></div>");
    }

    @Override
    public boolean appendChild(Component comp){
        NativeSpan nSpan = new NativeSpan();
        nSpan.setStyle("float:left; margin:2px;");
        nSpan.appendChild(comp);
        return super.appendChild(nSpan);
    }
    
    /**
     * @return the width
     */
    public String getWidth() {
        return (String)this.getDynamicProperty("width");
    }

    /**
     * @param width the width to set
     */
    public void setWidth(String width) {
        this.setDynamicProperty("width", width);
    }

    /**
     * @return the height
     */
    public String getHeight() {
        return (String)this.getDynamicProperty("height");
    }

    /**
     * @param height the height to set
     */
    public void setHeight(String height) {
        this.setDynamicProperty("height", height);
    }

    /**
     * @return the style
     */
    public String getStyle() {
        return (String)this.getDynamicProperty("style");
    }

    /**
     * @param style the style to set
     */
    public void setStyle(String style) {
        this.setDynamicProperty("style", style);
    }
}

NativeSpan is used to wrap each appended component, so here it is:

import org.zkoss.zk.ui.HtmlNativeComponent;

/**
*
* @author Richard Lovell
*/
public class NativeSpan extends HtmlNativeComponent {

public NativeSpan(){
this.setTag("span");
}

/**
* @return the width
*/
public String getWidth() {
return (String)this.getDynamicProperty("width");
}

/**
* @param width the width to set
*/
public void setWidth(String width) {
this.setStyle("display:inline-block;width:"+width);//width for span determined in CSS
}

/**
* @return the height
*/
public String getHeight() {
return (String)this.getDynamicProperty("height");
}

/**
* @param height the height to set
*/
public void setHeight(String height) {
this.setDynamicProperty("height", height);
}

/**
* @return the style
*/
public String getStyle() {
return (String)this.getDynamicProperty("style");
}

/**
* @param style the style to set
*/
public void setStyle(String style) {
this.setDynamicProperty("style", style);
}
}

This is nothing fancy, but having these corresponding native classes is a great convenience. I haven't tried them in a zul file, but I'm pretty sure they could also be used there with this at the top:

<?component name="nativehlayout" class="my.package.NativeHlayout" ?>

I'm not saying take away the current implementation for native comps because it lends versatility - just add a native component library that corresponds to the core components. Would this be a good candidate for a feature request?

delete flag offensive retag edit

11 Replies

Sort by ยป oldest newest

answered 2011-11-12 03:18:50 +0800

RichardL gravatar image RichardL
768 4

Feature request added. See http://tracker.zkoss.org/browse/ZK-584

link publish delete flag offensive edit

answered 2011-12-06 14:37:46 +0800

RichardL gravatar image RichardL
768 4

updated 2011-12-06 14:40:25 +0800

I think I've been a little off track with my understanding of how Native components work which has led me to envisage the Native component library. My preconception that "everything in Java is possible in ZUML" and vice versa misled me. It does also mention in the documentation that "You could use the native namespace in Java too". I made my own Native classes in Java, extending HtmlNativeComponent, thinking that they would be handled the same way as if they were in ZUML. Then I found out that the way Native classes save space on the server is through a process of consolidation - "..though the native HTML tags will be generated for the native namespace, ZK Loader actually creates a component to represent as many as these native HTML tags". I saw that the HtmlNativeComponent class had an addDeclaredNamespace method, so I thought it was still possible to achieve through Java classes. All along I was wondering: how could this consolidation happen in Java? Then I realized - it's not. It's done only in ZUML by the XML parsing through idom (please correct me if I'm wrong). So, long story short, it's possible to write Native components in Java but they will not be consolidated.

The question is, if we need to keep native components in ZUML docs, what can we do if we need to write logic into them? For example, if you want to wrap a component with padding when it is appended, like in Hlayout, etc. I coded a Native Grid component in Java, that looks just like the standard Grid comp, and wanted to use it for Grids that didn't require paging. You would think this would be possible using standard MVC, but Native components implement the NonFellow interface, which means trying to get the comp by id will always return null, so it's also not possible to access the ZUML Native components from the controller. This seems to be one of the main things standing in the way of Native component development - it also doesn't help that standard and native components don't share any of the same interfaces.

I really want to take the best steps toward making my application scalable and don't want to use highly dynamic components (and their client-side counterparts) if they're not necessary. I also want to build modular Native components with the option of building in simple logic. Anyone?

link publish delete flag offensive edit

answered 2011-12-07 01:26:00 +0800

RichardL gravatar image RichardL
768 4

Thinking about it more, I guess the consolidation in Java is done - it's just done manually. The developer can set the prolog and epilog with Strings of opening and closing HTML elements, and this would be the same as would the XML parsing would be attempting to do. It would, in fact, save the parser from doing the job if Native components are implemented in Java.

In this case, could someone confirm that the addDeclaredNamespace is not necessary for Native java classes? Also, will there be a time where it's possible to access Native components that are in ZUML from a composer (through auto-wiring)? Or use custom Native classes inside a ZUML doc?

link publish delete flag offensive edit

answered 2011-12-07 01:26:31 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

Hi Richard,

Recently I am experimenting with some native component sets, like this in ZUL page.

<zk>
	<zscript>
	List list1 = new LinkedList();
	    for(int j=0; j < 1; ++j) {
	    	List l = new ArrayList();
	    	for(int z=0; z < 10; ++z) {
			      l.add("option "+z);
			    }
	    	list1.add(new ListModelList(l));
	    }
	ListModel strset1 = new ListModelList(list1);
	</zscript>
	<table model="${strset1}">
		<template name="model">
			<tr model="${each}">
				<template name="model">
					<td text="${each}" style="border:1px solid blue">
						<attribute name="onClick">
						 Clients.evalJavaScript("jq.alert(jq('#" + event.uuid +"').text())");
						</attribute>
					</td>
				</template>
			</tr>
		</template>
	</table>
</zk>

The Table/Tr/Td are all native component and can directly use in zul page, and the native component can still use EventListener to listen some Client events, if you require.

Here is the Java code that does the same result.

List<List<String>> list1 = new LinkedList<List<String>>();
for(int j=0; j < 30; ++j) {
	List<String> l = new ArrayList<String>();
	for(int z=0; z < 10; ++z) {
		  l.add("option "+z);
		}
	list1.add(l);
}
new Table().render(new ListModelList<List<String>>(list1), new ElementRenderer<Tr, List<String>>() {
	public void render(Tr elem, List<String> data) throws Exception {
		elem.render(new ListModelList<String>(data), new ElementRenderer<Td, String>() {
			public void render(Td td, String d) throws Exception {
				td.text(d).attr("style", "color:red").appendChild(new Textbox());
			}
		});
	}
}).setParent(comp);

As you can see, the Java API I used is JQuery-like API and use ZK ListModel to render the HTML content.
Do you have any suggestion for this?

link publish delete flag offensive edit

answered 2011-12-07 03:30:42 +0800

RichardL gravatar image RichardL
768 4

Hi Jumper,
Thanks for your reply. How are your native components recognized in ZUML? I tried this with a component declaration at the top pointing at the class location but it didn't have any effect.

I wrote some blogs about ZK native (to aid my own understanding and help others) but took them down because my previous post's musings. I've put them back up and will edit them with my updated understanding in the coming days.

This one outlines the a native Grid component: http://richjava.wordpress.com/2011/12/06/native-grid/

I've been meaning to create a ZK Fiddle to show how it works.

link publish delete flag offensive edit

answered 2011-12-07 10:42:44 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

Hi Richard,

If you want to use the native component in zul page, you have to provide a lang-addon.xml and then declare your native component there.
For example,

<component>
	<component-name>table</component-name>
	<component-class>org.zkoss.html.Table</component-class>
</component>
<component>
	<component-name>tr</component-name>
	<component-class>org.zkoss.html.Tr</component-class>
</component>
<component>
	<component-name>td</component-name>
	<component-class>org.zkoss.html.Td</component-class>
</component>

link publish delete flag offensive edit

answered 2011-12-07 10:56:58 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

@Richard,

By the way, you can consider to put your code on github, if you want to be open source, then we can discuss there.

link publish delete flag offensive edit

answered 2011-12-07 21:24:35 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

Hmmmm, am i right that the memory footprint of the components can be ordered like this:

- normal component (high)
- component with stubonly="true" (moderate)
- native component (low)

So, i'm a little bit confused what is the difference between 'stubonly components' and 'native components'

thanks
Stephan

link publish delete flag offensive edit

answered 2011-12-08 01:00:40 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

for memory footprint, the stubonly and native component are not much different, but in client side widget, they are so different.

link publish delete flag offensive edit

answered 2011-12-08 05:55:03 +0800

RichardL gravatar image RichardL
768 4

Thanks, Jumper. I'll set up a dedicated project, sort out the lang-addon, and push it to Github.

I actually think that the best solution to Native components would be to keep the implementation transparent from the developer - in a standard ZK component, have a boolean field that holds its dynamic state (i.e. isDynamic). Conditions need to be satisfied that the component is dynamic before creating the client-side widget, and if they aren't satisfied the component is outputted as Native. For example, if a component has a listener added to it or if a Grid has paging set to true, and the list size is greater than the page size. In these cases the isDynamic field would be set to true and the component would be set up to handle AU requests, otherwise it is Native. What do you think?

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2011-11-11 03:24:11 +0800

Seen: 522 times

Last updated: Dec 08 '11

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More