JavaHelp 2 and ZK 5

From Documentation
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
JavaHelp 2 and ZK 5

Author
Nelson Cazonda, Developer at BCI


Nelson cazonda.jpg
Nelson been in the development area since 2003. He became a professional Java Developer in 2007. At present (2009) he is a full time developer at a financial institution in mozambique. There he deals with a variety of technologies/tools while ZK is the main framework for the presentation layer.

Date
October 23, 2009
Version
ZK 5.0.0-RC


Introduction

It's often common to see developers pay little or no attention when it comes to provide a help system in their applications, but for the final user it is a very important tool to understand how the application works and solve small problems without calling the help desk. Let's say you are not one of those developers I described on the first paragraph and you want to build your ZK applications with a professional looking help system, in that case you are reading the right article. In this article we will use ZK to manipulate a JavaHelp 2 HelpSet. I will not discuss what JavaHelp is and I will not tell you how to author JavaHelp files. If you need information on that find some useful links at the end of the article (Resources). This example have been tested on ZK 5.0.0-RC but it will certainly work on previous version of ZK.

Pre-requisites

  • JavaHelp 2.0_05, download it here;
  • ZK 5, download it here;
  • Java SDK 6, download it here;
  • Tomcat 6, download it here;
  • The example was developed using Eclipse Galileo but you can use any IDE of your choice.

After downloading the necessary tools and creating a new project on your IDE do the following:

  1. Copy the file <JAVA_HELP_FOLDER>/javahelp/lib/jh.jar to the lib folder of your project
  2. Create a folder named help on the WebContent folder of your eclipse project and extract the contents of <JAVA_HELP_FOLDER>/demo/hsjar/invertebrates.jar there

Source Code

help.zul the ZK code with the page skeleton. It has a border layout with a tab box on the west and an iframe on the center. The tab box will contain tabs each showing the TOC, Index, Search, Glossary or Favorites view depending on the configuration of your helpset file. These tabs are dynamically built by the Help class. The example shown here only supports TOC, Index and Search views but it's easy to extend it to support the other two views missing.

<window id="win" border="none" width="700px" height="800px"
	use="example.zk.help.Help" title="Help Demo" >
	<borderlayout>
		<west size="30%" collapsible="true" flex="true">
			<tabbox id="tbxNavigator" />
		</west>
		<center flex="true">
			<iframe id="iframe" width="100%" height="100%" />
		</center>
	</borderlayout>
</window>

Help.java Load the helpset file and pass it to the helpbroker

HelpSet helpSet = new HelpSet(null, new URL(HELP_SET_URL));
helpBroker = new ServletHelpBroker();
helpBroker.setHelpSet(helpSet);

Fill the tabbox (dynamically add the tabs and tab panels)

for (NavigatorView view : helpSet.getNavigatorViews()) {
	Tab tab = new Tab();
	tab.setId(view.getName());
	tab.setImage(IMAGES_FOLDER + view.getClass().getName()	+ ".gif");
	tbViews.appendChild(tab);

	Tabpanel tabpanel = new Tabpanel();
	if (view instanceof TOCView || view instanceof IndexView) {
		tabpanel.appendChild(drawTree(view));
	} else {// SearchView
		Toolbar srchToolbar = new Toolbar();

		// the search textbox
		txtSearch = new Textbox();
		srchToolbar.appendChild(txtSearch);

		// the search button
		Toolbarbutton btnSearch = new Toolbarbutton();
		btnSearch.setImage(IMAGES_FOLDER+ "javax.help.SearchView.gif");
		btnSearch.addEventListener(Events.ON_CLICK,
				new EventListener() {
					public void onEvent(Event arg0) throws Exception {
						handleListClick(txtSearch.getValue());
					}
				});
		srchToolbar.appendChild(btnSearch);

		// the list box that will display the search results
		lstSrchResults = new Listbox();
		lstSrchResults.setVisible(false);
		lstSrchResults.addEventListener(Events.ON_SELECT,  new SearchResultListListener());
		srchToolbar.appendChild(lstSrchResults);

		lblNoResultsFound = new Label("No Results Found!");
		lblNoResultsFound.setVisible(false);

		tabpanel.appendChild(srchToolbar);
		tabpanel.appendChild(lblNoResultsFound);

		searcher = new ZkHelpSearcher((SearchView) view);
	}
	tpViews.appendChild(tabpanel);
}

Convert the JavaHelp TOCView or IndexView into a ZK Tree component

private Tree drawTree(Object view) {
	DefaultMutableTreeNode topNode = null;
	if (view instanceof TOCView) {
		topNode = ((TOCView) view).getDataAsTree();
	} else if (view instanceof IndexView) {
		topNode = ((IndexView) view).getDataAsTree();
	} else {
		return null;
	}

	Enumeration treeEnum = topNode.children();
	Tree tree = new Tree();
	Treechildren tc = new Treechildren();
	while (treeEnum.hasMoreElements()) {
		DefaultMutableTreeNode n = (DefaultMutableTreeNode) treeEnum.nextElement();
 	        tc.appendChild(addNode(n));
	}
	tree.appendChild(tc);
	tree.addEventListener(Events.ON_SELECT, new TreeListener());
	((Treeitem) ((Treechildren) tree.getFirstChild()).getFirstChild()).setOpen(true);
	tree.setZclass("z-dottree");
	return tree;
}

addNode() is used by drawTree to recursively create tree items

private Treeitem addNode(DefaultMutableTreeNode node) {
	Treeitem parent = null;
	Object item = node.getUserObject();
	if (item instanceof TOCItem) {
		TOCItem ti = (TOCItem) item;
		parent = new Treeitem(ti.getName(), item);
	} else if (item instanceof IndexItem) {
		parent = new Treeitem(((IndexItem) item).getName(), item);
	}

	Treechildren treeChildren = null;
	Enumeration e = node.children();
	if (e.hasMoreElements()) {
		treeChildren = new Treechildren();
	}

	while (e.hasMoreElements()) {
		DefaultMutableTreeNode child = (DefaultMutableTreeNode) e	.nextElement();
		treeChildren.appendChild(addNode(child));
	}

	if (treeChildren != null) {
		parent.setImage(IMAGES_FOLDER + "chapTopic.gif");
		parent.appendChild(treeChildren);
	} else {
		parent.setImage(IMAGES_FOLDER + "topic.gif");
	}

	return parent;
}

ZkHelpSearcher.java Is the class responsible for the search logic. Implements the JavaHelp System's SearchListener. Most of the code in this class is a small modification of the JavaHelp's source.

public synchronized List<Listitem> search(String query) {
	List<Listitem> searchResults = new ArrayList<Listitem>();
	if (searchquery.isActive()) {
		searchquery.stop();
	}
	searchquery.start(query, Locale.getDefault());
	if (!searchFinished) {
		try {
			wait();
		} catch (InterruptedException e) {
		}
	}
	while (srchResultEnum.hasMoreElements()) {
		SearchTOCItem item = (SearchTOCItem) srchResultEnum.nextElement();
		Listitem auxListItem = new Listitem(item.getName(), item);
		auxListItem.setImage(toImage(item.getConfidence()));
		searchResults.add(auxListItem);
	}
	return searchResults;
}

TreeListener.java Handle tree clicks

public void onEvent(Event event) throws Exception {
	Tree tree = (Tree) event.getTarget();
	//ZK tree item
	Treeitem zkTreeitem = tree.getSelectedItem();
		
	//JAVAHELP tree item
	TreeItem jhTreeItem = (TreeItem) zkTreeitem.getValue();
		
	Iframe iframe = (Iframe) tree.getFellow("iframe");
	iframe.setSrc(jhTreeItem.getURL().toString());
}

SearchResultListListener.java Handle the clicks on the search result list

public void onEvent(Event event) throws Exception {
	Listbox list = (Listbox) event.getTarget();
	Listitem listitem = list.getSelectedItem();
		
	SearchTOCItem searchTOCItem = (SearchTOCItem) listitem.getValue();
		
	Iframe iframe = (Iframe) list.getFellow("iframe");
	iframe.setSrc(searchTOCItem.getURL().toString());
}

Download

  • Download the source code (Eclipse Galileo project) here
  • Download the demo application (*.war file) here

Resources

Summary

Although JavaHelp System was designed with desktop applications in mind we've seen that it's possible to use it in web applications with little effort. In this article, I demonstrated how to use JavaHelp as a mechanism to provide professional help to the end user of your web applications. As a next step, it would be nice to create a ZK component to simplify the things. I'm working on that and I hope to finish soon and share it with the community.



Copyright © Nelson Cazonda. This article is licensed under GNU Free Documentation License.