net.sf.click
Interface Control

All Superinterfaces:
Serializable
All Known Subinterfaces:
Container
All Known Implementing Classes:
AbstractContainer, AbstractControl, FieldSet

public interface Control
extends Serializable

Provides the interface for Page controls. Controls are sometimes referred to as components or widgets.

Please note AbstractControl provides a default implementation of the Control interface and allows easy creation of new controls.

When a Page request event is processed Controls may perform server side event processing through their onProcess() method. Controls are generally rendered in a Page by calling their toString() method.

The Control execution sequence is illustrated below:

HTML Header Imports

Control HTML header imports can be exposed by overriding the getHtmlImports() method.

For example a custom TextField control specifies that the custom.js file should be included in the HTML header imports:

 public class CustomField extends TextField {

     protected static final String HTML_IMPORT =
         "<script type=\"text/javascript\" src=\"{0}/click/custom.js\"></script>\n";

     public String getHtmlImports() {
         String[] args = { getContext().getRequest().getContextPath() };
         return MessageFormat.format(HTML_IMPORTS, args);
     }

     ..
 } 
Please note multiple import lines should be separated by a '\n' char, as the PageImports will parse multiple import lines on the '\n' char and ensure that imports are not included twice.

Deploying Resources

The Click framework uses the Velocity Tools WebappLoader for loading templates. This avoids issues associate with using the Velocity ClasspathResourceLoader and FileResourceLoader on J2EE application servers. To make preconfigured resources (templates, stylesheets, etc.) available to web applications Click automatically deploys configured classpath resources to the /click directory at startup (existing files will not be overwritten).

To enable Controls to deploy static resources on startup this interface provides an onDeploy(ServletContext) method.

Continuing our example the CustomField control deploys its custom.js file to the /click directory:

 public class CustomField extends TextField {
     ..

     public void onDeploy(ServletContext servletContext) {
         ClickUtils.deployFile
             (servletContext, "/com/mycorp/control/custom.js", "click");
     }
 } 
Controls using the onDeploy() method must be registered in the application WEB-INF/click.xml for them to be invoked. For example:
 <click-app>
   <pages package="com.mycorp.page" automapping="true"/>

   <controls>
     <control classname="com.mycorp.control.CustomField"/>
   </controls>
 </click-app> 
When the Click application starts up it will deploy any control elements defined in the following files in sequential order:

Click also supports an alternative deployment strategy which relies on packaging resource (stylesheets, JavaScript, images etc.) following a specific convention. See the section Deploying Custom Resources for further details.

Author:
Malcolm Edgar
See Also:
PageImports

Field Summary
static String CONTROL_MESSAGES
          The global control messages bundle name:   click-control.
 
Method Summary
 Context getContext()
          Deprecated. getContext() is now obsolete on the Control interface, but will still be available on AbstractControl: AbstractControl.getContext()
 String getHtmlImports()
          Return the HTML import string to be include in the page.
 String getId()
          Return HTML element identifier attribute "id" value.
 Map getMessages()
          Return the localized messages Map of the Control.
 String getName()
          Return the name of the Control.
 Object getParent()
          Return the parent of the Control.
 void onDeploy(ServletContext servletContext)
          The on deploy event handler, which provides classes the opportunity to deploy static resources when the Click application is initialized.
 void onDestroy()
          The on destroy request event handler.
 void onInit()
          The on initialize event handler.
 boolean onProcess()
          The on process event handler.
 void onRender()
          The on render event handler.
 void render(HtmlStringBuffer buffer)
          Render the control's HTML representation to the specified buffer.
 void setListener(Object listener, String method)
          Deprecated. this method is now obsolete on the Control interface, but will still be available on AbstractControl: AbstractControl.setListener(java.lang.Object, java.lang.String)
 void setName(String name)
          Set the name of the Control.
 void setParent(Object parent)
          Set the parent of the Control.
 

Field Detail

CONTROL_MESSAGES

public static final String CONTROL_MESSAGES
The global control messages bundle name:   click-control.

See Also:
Constant Field Values
Method Detail

getContext

public Context getContext()
Deprecated. getContext() is now obsolete on the Control interface, but will still be available on AbstractControl: AbstractControl.getContext()

Return the Page request Context of the Control.

Returns:
the Page request Context

getHtmlImports

public String getHtmlImports()
Return the HTML import string to be include in the page.

Override this method to specify JavaScript and CSS includes for the page. For example:

 protected static final String HTML_IMPORT =
     "<script type=\"text/javascript\" src=\"{0}/click/custom.js\"></script>";

 public String getHtmlImports() {
     return ClickUtils.createHtmlImport(HTML_IMPORTS, getResourceVersionIndicator(), getContext());
 } 
Note multiple import lines should be separated by a '\n' char, as the PageImports will parse multiple import lines on the '\n' char and ensure that imports are not included twice.

The order in which JS and CSS files are include will be preserved in the page.

Also note: a common problem when overriding getHtmlImports in subclasses is forgetting to call super.getHtmlImports. Consider carefully whether you should call super.getHtmlImports or not.

Returns:
the HTML includes statements for the control stylesheet and JavaScript files, or null if no includes are available

getId

public String getId()
Return HTML element identifier attribute "id" value. AbstractControl.getId()

Returns:
HTML element identifier attribute "id" value

setListener

public void setListener(Object listener,
                        String method)
Deprecated. this method is now obsolete on the Control interface, but will still be available on AbstractControl: AbstractControl.setListener(java.lang.Object, java.lang.String)

Set the controls event listener.

The method signature of the listener is:

An example event listener method would be:

 public boolean onClick() {
     System.out.println("onClick called");
     return true;
 } 

Parameters:
listener - the listener object with the named method to invoke
method - the name of the method to invoke

getMessages

public Map getMessages()
Return the localized messages Map of the Control.

Returns:
the localized messages Map of the Control

getName

public String getName()
Return the name of the Control. Each control name must be unique in the containing Page model or the containing Form.

Returns:
the name of the control

setName

public void setName(String name)
Set the name of the Control. Each control name must be unique in the containing Page model or the parent container.

Please note: changing the name of a Control after it has been added to its parent container is undefined. Thus it is best not to change the name of a Control once its been set.

Parameters:
name - of the control
Throws:
IllegalArgumentException - if the name is null

getParent

public Object getParent()
Return the parent of the Control.

Returns:
the parent of the Control

setParent

public void setParent(Object parent)
Set the parent of the Control.

Parameters:
parent - the parent of the Control

onDeploy

public void onDeploy(ServletContext servletContext)
The on deploy event handler, which provides classes the opportunity to deploy static resources when the Click application is initialized.

For example:

 public void onDeploy(ServletContext servletContext) throws IOException {
     ClickUtils.deployFile
         (servletContext, "/com/mycorp/control/custom.js", "click");
 } 
Please note: a common problem when overriding onDeploy in subclasses is forgetting to call super.onDeploy. Consider carefully whether you should call super.onDeploy or not.

Click also supports an alternative deployment strategy which relies on packaging resource (stylesheets, JavaScript, images etc.) following a specific convention. See the section Deploying Custom Resources for further details.

Parameters:
servletContext - the servlet context

onInit

public void onInit()
The on initialize event handler. Each control will be initialized before its onProcess() method is called.

Container implementations should recursively invoke the onInit method on each of their child controls ensuring that all controls receive this event.

Please note: a common problem when overriding onInit in subclasses is forgetting to call super.onInit(). Consider carefully whether you should call super.onInit() or not, especially for Containers which by default call onInit on all their child controls as well.


onProcess

public boolean onProcess()
The on process event handler. Each control will be processed when the Page is requested.

ClickServlet will process all Page controls in the order they were added to the Page.

Container implementations should recursively invoke the onProcess method on each of their child controls ensuring that all controls receive this event. However when a control onProcess method return false, no other controls onProcess method should be invoked.

When a control is processed it should return true if the Page should continue event processing, or false if no other controls should be processed and the Page.onGet() or Page.onPost() methods should not be invoked.

Please note: a common problem when overriding onProcess in subclasses is forgetting to call super.onProcess(). Consider carefully whether you should call super.onProcess() or not, especially for Containers which by default call onProcess on all their child controls as well.

Returns:
true to continue Page event processing or false otherwise

onRender

public void onRender()
The on render event handler. This event handler is invoked prior to the control being rendered, and is useful for providing pre rendering logic.

The on render method is typically used to populate tables performing some database intensive operation. By putting the intensive operations in the on render method they will not be performed if the user navigates away to a different page.

Container implementations should recursively invoke the onRender method on each of their child controls ensuring that all controls receive this event.

Please note: a common problem when overriding onRender in subclasses is forgetting to call super.onRender(). Consider carefully whether you should call super.onRender() or not, especially for Containers which by default call onRender on all their child controls as well.


onDestroy

public void onDestroy()
The on destroy request event handler. Control classes should use this method to add any resource clean up code.

This method is guaranteed to be called before the Page object reference goes out of scope and is available for garbage collection.

Container implementations should recursively invoke the onDestroy method on each of their child controls ensuring that all controls receive this event.

Please note: a common problem when overriding onDestroy in subclasses is forgetting to call super.onDestroy(). Consider carefully whether you should call super.onDestroy() or not, especially for Containers which by default call onDestroy on all their child controls as well.


render

public void render(HtmlStringBuffer buffer)
Render the control's HTML representation to the specified buffer. The control's Object.toString() method should delegate the rendering to the render method for improved performance.

An example implementation:

 public class Border extends AbstractContainer {

     public String toString() {
         int estimatedSizeOfControl = 100;
         HtmlStringBuffer buffer = new HtmlStringBuffer(estimatedSizeOfControl);
         render(buffer);
         return buffer.toString();
     }

     /**
      * @see Control#render(HtmlStringBuffer)
      */
     public void render(HtmlStringBuffer buffer) {
         buffer.elementStart("div");
         buffer.appendAttribute("name", getName());
         buffer.closeTag();
         buffer.append(getField());
         buffer.elementEnd("div");
     }
 }
 

Parameters:
buffer - the specified buffer to render the control's output to