|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface Control
Provides the interface for Page controls. Controls are also referred to as components or widgets.
When a Page request event is processed Controls may perform server side event processing through theironProcess()
method. Controls are generally
rendered in a Page by calling their toString() method.
The Control execution sequence is illustrated below:
getHeadElements()
method.
Below is an example of a custom TextField control specifying that the
custom.js file should be included in the HTML HEADer:
public class CustomField extends TextField {
public List getHeadElements() {
if(headElements == null) {
// If headElements is null, create default headElements
headElements = super.getHeadElements();
// Add a new JavaScript Import Element for the "/custom.js" script
headElements.add(new JsImport("/click/custom.js"));
}
return headElements;
}
..
}
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:
AbstractControl
provides
a default implementation of the Control interface to make it easier for
developers to create their own controls.
PageImports
Field Summary | |
---|---|
static String |
CONTROL_MESSAGES
The global control messages bundle name: click-control. |
Method Summary | |
---|---|
Set<Behavior> |
getBehaviors()
Returns the list of behaviors for this control. |
Context |
getContext()
Deprecated. getContext() is now obsolete on the Control interface, but will still be available on AbstractControl: AbstractControl.getContext() |
List<Element> |
getHeadElements()
Return the list of HEAD elements
to be included in the page. |
String |
getId()
Return HTML element identifier attribute "id" value. |
Map<String,String> |
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. |
boolean |
hasBehaviors()
Returns true if this control has any Behaviors registered, false otherwise. |
boolean |
isAjaxTarget(Context context)
Returns true if this control is an Ajax target, false otherwise. |
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 |
---|
static final String CONTROL_MESSAGES
Method Detail |
---|
Context getContext()
AbstractControl.getContext()
List<Element> getHeadElements()
elements
to be included in the page. Example HEAD elements include
JsImport
,
JsScript
,
CssImport
and
CssStyle
.
Controls can contribute their own list of HEAD elements by implementing
this method.
The recommended approach when implementing this method is to use
lazy loading to ensure the HEAD elements are only added
once and when needed. For example:
public MyControl extends AbstractControl { public List getHeadElements() { // Use lazy loading to ensure the JS is only added the // first time this method is called. if (headElements == null) { // Get the head elements from the super implementation headElements = super.getHeadElements(); // Include the control's external JavaScript resource JsImport jsImport = new JsImport("/mycorp/mycontrol/mycontrol.js"); headElements.add(jsImport); // Include the control's external Css resource CssImport cssImport = new CssImport("/mycorp/mycontrol/mycontrol.css"); headElements.add(cssImport); } return headElements; } }Alternatively one can add the HEAD elements in the Control's constructor:
public MyControl extends AbstractControl { public MyControl() { JsImport jsImport = new JsImport("/mycorp/mycontrol/mycontrol.js"); getHeadElements().add(jsImport); CssImport cssImport = new CssImport("/mycorp/mycontrol/mycontrol.css"); getHeadHeaders().add(cssImport); } }One can also add HEAD elements from event handler methods such as
onInit()
, onProcess()
, onRender()
etc.
The order in which JS and CSS files are included will be preserved in the
page.
Note: this method must never return null. If no HEAD elements
are available this method must return an empty List
.
Also note: a common problem when overriding getHeadElements in
subclasses is forgetting to call super.getHeadElements. Consider
carefully whether you should call super.getHeadElements or not.
String getId()
AbstractControl.getId()
void setListener(Object listener, String method)
AbstractControl.setListener(java.lang.Object, java.lang.String)
public boolean onClick() { System.out.println("onClick called"); return true; }
listener
- the listener object with the named method to invokemethod
- the name of the method to invokeMap<String,String> getMessages()
String getName()
void setName(String name)
name
- of the control
IllegalArgumentException
- if the name is nullObject getParent()
void setParent(Object parent)
parent
- the parent of the Controlvoid onDeploy(ServletContext servletContext)
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.
servletContext
- the servlet contextvoid onInit()
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 Container
s which by default
call onInit on all their child controls as well.
boolean onProcess()
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 Container
s which by default
call onProcess on all their child controls as well.
void onRender()
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 Container
s which by default
call onRender on all their child controls as well.
void onDestroy()
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 Container
s which by default
call onDestroy on all their child controls as well.
void render(HtmlStringBuffer buffer)
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"); } }
buffer
- the specified buffer to render the control's output toboolean hasBehaviors()
Set<Behavior> getBehaviors()
boolean isAjaxTarget(Context context)
ControlRegistry.registerAjaxTarget
.
When the Click handles an Ajax request it iterates the Controls
registered with the ControlRegistry
and checks if one of them is the Ajax target by calling
isAjaxTarget
. If isAjaxTarget
returns true, Click will process that Control's behaviors
.
Please note: there can only be one target control, so the first
Control that is identified as the Ajax target will be processed, the other
controls will be skipped.
The most common way to check whether a Control is the Ajax target is to
check if its ID
is available as a request parameter:
public MyControl extends AbstractControl { ... public boolean isAjaxTarget(Context context) { return context.hasRequestParameter(getId()); } }Not every scenario can be covered through an ID attribute though. For example if an ActionLink is rendered multiple times on the same page, it cannot have an ID attribute, as that would lead to duplicate IDs, which isn't allowed by the HTML specification. Control implementations has to cater for how the control will be targeted. In the case of ActionLink it might check against its id, and if that isn't available check against its name.
context
- the request context
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |