Author(s)Jonathan Locke, Chris Turner, Eelco Hillenius, Johan Compagner, Juergen Donnerstag, Igor Vaynberg (ivaynberg)
Component serves as the highest level abstract base class for all components.
Identity - All Components must have a non-null id which is
retrieved by calling getId(). The id must be unique within the
MarkupContainer that holds the Component, but does not have to be globally
unique or unique within a Page's component hierarchy.
Hierarchy - A component has a parent which can be retrieved with
getParent(). If a component is an instance of MarkupContainer, it may have
children. In this way it has a place in the hierarchy of components contained
on a given page. The isAncestorOf(Component) method returns
true if this Component is an ancestor of the given Component.
Component Paths - The path from the Page at the root of the
component hierarchy to a given Component is simply the concatenation with dot
separators of each id along the way. For example, the path "a.b.c" would
refer to the component named "c" inside the MarkupContainer named "b" inside
the container named "a". The path to a component can be retrieved by calling
getPath(). This path is an absolute path beginning with the id of the Page at
the root. Pages bear a PageMap/Session-relative identifier as their id, so
each absolute path will begin with a number, such as "0.a.b.c". To get a
Component path relative to the page that contains it, you can call
getPageRelativePath().
LifeCycle - Components participate in the following lifecycle
phases:
Construction - A Component is constructed with the Java language
new operator. Children may be added during construction if the Component is a
MarkupContainer.
Request Handling - An incoming request is processed by a protocol
request handler such as WicketServlet. An associated Application object
creates Session, Request and Response objects for use by a given Component in
updating its model and rendering a response. These objects are stored inside
a container called RequestCycle which is accessible via
getRequestCycle() . The convenience methods
getRequest() , getResponse() and
getSession() provide easy access to the contents of this
container.
Listener Invocation - If the request references a listener on an
existing Component, that listener is called, allowing arbitrary user code to
handle events such as link clicks or form submits. Although arbitrary
listeners are supported in Wicket, the need to implement a new class of
listener is unlikely for a web application and even the need to implement a
listener interface directly is highly discouraged. Instead, calls to
listeners are routed through logic specific to the event, resulting in calls
to user code through other overridable methods. For example, the
onFormSubmitted() method
implemented by the Form class is really a private implementation detail of
the Form class that is not designed to be overridden (although unfortunately,
it must be public since all interface methods in Java must be public).
Instead, Form subclasses should override user-oriented methods such as
onValidate(), onSubmit() and onError() (although only the latter two are
likely to be overridden in practice).
Form Submit - If a Form has been submitted and the Component is a
FormComponent, the component's model is validated by a call to
FormComponent.validate().
Form Model Update - If a valid Form has been submitted and the
Component is a FormComponent, the component's model is updated by a call to
FormComponent.updateModel().
Rendering - A markup response is generated by the Component via
render() , which calls subclass implementation code
contained in onRender() . Once this phase begins, a
Component becomes immutable. Attempts to alter the Component will result in a
WicketRuntimeException.
Component Models - The primary responsibility of a component is
to use its model (an object that implements IModel), which can be set via
setModel(IModel) and retrieved via
getModel() , to render a response in an appropriate markup
language, such as HTML. In addition, form components know how to update their
models based on request information. Since the IModel interface is a wrapper
around an actual model object, a convenience method
getModelObject() is provided to retrieve the model Object
from its IModel wrapper. A further convenience method,
getModelObjectAsString() , is provided for the very common
operation of converting the wrapped model Object to a String.
Visibility - Components which have setVisible(false) will return
false from isVisible() and will not render a response (nor will their
children).
Page - The Page containing any given Component can be retrieved
by calling getPage() . If the Component is not attached to
a Page, an IllegalStateException will be thrown. An equivalent method,
findPage() is available for special circumstances where it
might be desirable to get a null reference back instead.
Session - The Page for a Component points back to the Session
that contains the Page. The Session for a component can be accessed with the
convenience method getSession(), which simply calls getPage().getSession().
Locale - The Locale for a Component is available through the
convenience method getLocale(), which is equivalent to
getSession().getLocale().
String Resources - Components can have associated String
resources via the Application's Localizer, which is available through the
method getLocalizer() . The convenience methods
getString(String) and
getString(String, IModel) wrap the identical
methods on the Application Localizer for easy access in Components.
Style - The style ("skin") for a component is available through
getStyle() , which is equivalent to
getSession().getStyle(). Styles are intended to give a particular look to a
Component or Resource that is independent of its Locale. For example, a style
might be a set of resources, including images and markup files, which gives
the design look of "ocean" to the user. If the Session's style is set to
"ocean" and these resources are given names suffixed with "_ocean", Wicket's
resource management logic will prefer these resources to other resources,
such as default resources, which are not as good of a match.
Variation - Whereas Styles are Session (user) specific,
variations are component specific. E.g. if the Style is "ocean" and the
Variation is "NorthSea", than the resources are given the names suffixed with
"_ocean_NorthSea".
AttributeModifiers - You can add one or more
AttributeModifier s to any component if you need to programmatically
manipulate attributes of the markup tag to which a Component is attached.
Application, ApplicationSettings and ApplicationPages - The
getApplication() method provides convenient access to the Application for a
Component via getSession().getApplication(). The getApplicationSettings()
method is equivalent to getApplication().getSettings(). The
getApplicationPages is equivalent to getApplication().getPages().
Feedback Messages - The debug(String) ,
info(String) , warn(String) ,
error(String) and fatal(String) methods
associate feedback messages with a Component. It is generally not necessary
to use these methods directly since Wicket validators automatically register
feedback messages on Components. Any feedback message for a given Component
can be retrieved with getFeedbackMessage() .
Page Factory - It is possible to change the way that Pages are
constructed by overriding the getPageFactory() method,
returning your own implementation of IPageFactory .
Versioning - Pages are the unit of versioning in Wicket, but
fine-grained control of which Components should participate in versioning is
possible via the setVersioned(boolean) method. The
versioning participation of a given Component can be retrieved with
isVersioned() .
AJAX support- Components can be re-rendered after the whole Page
has been rendered at least once by calling doRender().