ZK AJAX Status Bar

Seeing that my research project is a mini accounting system, I thought it necessary to be able to display items in a status bar, like a real application.  It is very slightly unfortunate that ZK doesn’t have something integrated right in for this purpose.  But, given the versatility of ZK, it’s easy enough to resolve.

Features

I thought it important to have some useful features that make sense for what I’ve seen in status bars.

  • a method to set the status, with a delay before the status bar is cleared
  • a method to simply set the status, and leave it as is.  It would be up to the developer to clear the status later, if need be.  Or, the next status item would take over.
  • a very simple interface abstraction in case we want to change the type of component we use later, or something of that nature.  This will help us prevent the need to refactor a lot of code that could be using the status bar; we would only need to refactor the implementing class of the interface, leaving all of the code accessing the status bar entirely intact.

Future features might include…

  • methods for setting the status with color text
  • methods for setting the status with html
  • any other suggestions are welcome.

Window Width Status Bar

We first, of course, need to setup the actual status bar.  So, right before the end of the window, we do just that, with a “textbox”.  Now, there’s no reason you can’t use some other type of control, if it makes sense to.

<textbox width="100%" height="1.2em" sclass="status" readonly="true"
         id="status" use="com.example.system.StatusBar" />
<timer id="statusTimer" running="false" repeats="false"
       onTimer='status.setText("");'/>

The text box is implemented by a custom class, which we’ll delve into in a moment.  We also have a ZK timer, for implementing the automatic clearing feature, because it is illegal to access ZK elements from outside of a ZK event.  i.e. You cannot write your own thread to do it at a later time, as ZK will throw an IllegalStateException.

The Code

Interface Abstraction

We’ve kept the interface very simple, just two methods.  For more information, read the javadoc comments.

  • setStatus(String) allows setting of the status bar permanently
  • setStatus(String, int) allows setting of the status bar, and automatic clearing of it after a specified delay
package com.example.system;
 
/**
 * Handles setting of status bar messages.  All calls to this object must be
 * done from within the ZK framework, such as inside an event.
 *
 * Hides the details of what component is actually a status bar.  It could be a
 * textbox, or something else, but we don't want to be dependant on any specific
 * type of control, in case it changes in the future.
 *
 * Created :  Jan 31, 2010 1:39:37 AM MST
 *
 * Modified : $Date$ UTC
 *
 * Revision : $Revision$
 *
 * @author Trenton D. Adams
 */
public interface IStatusBar
{
    /**
     * Sets the status bar text for the time period indicated.
     *
     * @param statusText status text
     * @param timePeriod delay in seconds, before the status bar will be
     *                   cleared.
     */
    public void setStatus(final String statusText, final int timePeriod);
 
    /**
     * Sets the status bar text.  Pass null to clear.
     *
     * @param statusText status text or null to clear
     */
    public void setStatus(final String statusText);
 
    /**
     * @return the status text of the status bar.
     */
    public String getStatus();
}

Implementation

Essentially, all we are doing with the implement is as follows

  • implement AfterCompose, so we can setup a session variable to access the status bar from any ZK code, without much trouble
  • implement the setStatus() methods as described in the feature section.  One takes an extra argument for a delay, indicating how long before the status bar should be cleared.
package com.example.system;
 
import org.apache.log4j.Logger;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Timer;
 
/**
 * StatusBar handles setting the status bar text, and clearing it after a given
 * timeout.  Implements IStatusBar, to hide the details of what a status bar is
 * from the client code.  We use a textbox, but we could change that, who knows.
 *
 * Created :  Jan 31, 2010 12:42:29 AM MST
 *
 * Modified : $Date$ UTC
 *
 * Revision : $Revision$
 *
 * @author Trenton D. Adams
 */
public class StatusBar extends Textbox implements AfterCompose, IStatusBar
{
    @SuppressWarnings({"ConstantNamingConvention"})
    private static final Logger logger = Logger.getLogger(StatusBar.class);
 
    public StatusBar()
    {
    }
 
    public void afterCompose()
    {
        logger.info("status bar running as " + getId());
        // TODO find a better method, getFellow() didn't work
        final Session session = getDesktop().getSession();
        session.setAttribute("status", this);
    }
 
    public void setStatus(final String statusText, final int timePeriod)
    {
        setStatus(statusText);
        // the timer must be in the page, or the page is inactive and this
        // call would never happen?
        final Timer timer = (Timer) getFellow("statusTimer");
        timer.setDelay(timePeriod * 1000);
        timer.start();
    }
 
    public void setStatus(final String statusText)
    {
        setText(statusText);
    }
 
    public String getStatus()
    {
        return getText();
    }
}

Using the Status Bar

The following code must be used inside of a ZK event handler, such as one that comes from the click of a button, or a mouse over event, etc.  Basically, all we’re doing is grabbing the status bar object from the session, and request the status be set.  That’s all there is to it.

final Session session = getDesktop().getSession();
final IStatusBar statusBar = (IStatusBar) session.getAttribute("status");
statusBar.setStatus("Transaction Posted", 5);

Results

I’m attaching a screen shot of the results of my status bar.

ZK Status bar

3 Replies to “ZK AJAX Status Bar”

  1. Or you could use Clients.evalJavaScript(String) and then set window.status in javascript – however note “It has no effect if the client doesn’t support JavaScript” 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *