You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by so...@apache.org on 2023/04/12 07:25:40 UTC
[wicket] branch WICKET-7044-guide-images created (now 00bda6bea6)
This is an automated email from the ASF dual-hosted git repository.
solomax pushed a change to branch WICKET-7044-guide-images
in repository https://gitbox.apache.org/repos/asf/wicket.git
at 00bda6bea6 [WICKET-7044] guide images are fixed
This branch includes the following new commits:
new 00bda6bea6 [WICKET-7044] guide images are fixed
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[wicket] 01/01: [WICKET-7044] guide images are fixed
Posted by so...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
solomax pushed a commit to branch WICKET-7044-guide-images
in repository https://gitbox.apache.org/repos/asf/wicket.git
commit 00bda6bea6a9b286539584a2a1e65a3c3a5231ac
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Wed Apr 12 14:25:22 2023 +0700
[WICKET-7044] guide images are fixed
---
.../src/main/asciidoc/advanced/advanced_2.adoc | 30 +++---
.../src/main/asciidoc/advanced/advanced_3.adoc | 10 +-
.../src/main/asciidoc/advanced/advanced_5.adoc | 12 +--
.../src/main/asciidoc/ajax/ajax_2.adoc | 108 ++++++++++-----------
.../src/main/asciidoc/ajax/ajax_6.adoc | 66 ++++++-------
.../asciidoc/bestpractices/bestpractices_16.adoc | 2 +-
.../asciidoc/bestpractices/bestpractices_5.adoc | 2 +-
.../componentLifecycle/componentLifecycle_1.adoc | 4 +-
.../src/main/asciidoc/forms2/forms2_11.adoc | 12 +--
.../src/main/asciidoc/forms2/forms2_12.adoc | 38 ++++----
.../src/main/asciidoc/forms2/forms2_2.adoc | 74 +++++++-------
.../src/main/asciidoc/forms2/forms2_3.adoc | 30 +++---
.../src/main/asciidoc/forms2/forms2_4.adoc | 2 +-
.../src/main/asciidoc/forms2/forms2_5.adoc | 26 ++---
.../src/main/asciidoc/helloWorld.adoc | 4 +-
.../src/main/asciidoc/helloWorld/helloWorld_2.adoc | 2 +-
.../src/main/asciidoc/helloWorld/helloWorld_3.adoc | 10 +-
.../src/main/asciidoc/howToSource.adoc | 4 +-
.../src/main/asciidoc/i18n/i18n_2.adoc | 18 ++--
.../src/main/asciidoc/i18n/i18n_3.adoc | 12 +--
.../src/main/asciidoc/internals/pagestoring.adoc | 12 +--
.../src/main/asciidoc/introduction.adoc | 6 +-
wicket-user-guide/src/main/asciidoc/jee/jee_1.adoc | 18 ++--
.../asciidoc/jsintegration/jsintegration_1.adoc | 8 +-
.../asciidoc/jsintegration/jsintegration_2.adoc | 42 ++++----
.../src/main/asciidoc/layout/layout_1.adoc | 10 +-
.../src/main/asciidoc/layout/layout_2.adoc | 6 +-
.../src/main/asciidoc/layout/layout_3.adoc | 34 +++----
.../src/main/asciidoc/maven/maven_2.adoc | 18 ++--
.../main/asciidoc/modelsforms/modelsforms_1.adoc | 8 +-
.../main/asciidoc/modelsforms/modelsforms_4.adoc | 2 +-
.../main/asciidoc/modelsforms/modelsforms_5.adoc | 2 +-
.../main/asciidoc/modelsforms/modelsforms_6.adoc | 2 +-
.../main/asciidoc/modelsforms/modelsforms_7.adoc | 22 ++---
.../src/main/asciidoc/monitoring/monitoring_2.adoc | 16 +--
wicket-user-guide/src/main/asciidoc/redirects.adoc | 8 +-
.../src/main/asciidoc/repeaters/repeaters_2.adoc | 12 +--
.../src/main/asciidoc/repeaters/repeaters_4.adoc | 26 ++---
.../requestProcessing/requestProcessing_3.adoc | 2 +-
.../requestProcessing/requestProcessing_4.adoc | 2 +-
.../src/main/asciidoc/resources/resources_14.adoc | 12 +--
.../src/main/asciidoc/resources/resources_3.adoc | 26 ++---
.../src/main/asciidoc/security/security_1.adoc | 18 ++--
.../src/main/asciidoc/security/security_2.adoc | 48 ++++-----
.../src/main/asciidoc/testing/testing_1.adoc | 50 +++++-----
.../asciidoc/testingspring/testingspring_2.adoc | 4 +-
.../src/main/asciidoc/urls/urls_6.adoc | 14 +--
.../versioningCaching/versioningCaching_2.adoc | 12 +--
.../src/main/asciidoc/whyLearn/whyLearn_2.adoc | 2 +-
.../main/asciidoc/wicketstuff/wicketstuff_2.adoc | 4 +-
.../main/asciidoc/wicketstuff/wicketstuff_4.adoc | 6 +-
.../main/asciidoc/wicketstuff/wicketstuff_5.adoc | 10 +-
52 files changed, 464 insertions(+), 464 deletions(-)
diff --git a/wicket-user-guide/src/main/asciidoc/advanced/advanced_2.adoc b/wicket-user-guide/src/main/asciidoc/advanced/advanced_2.adoc
index 0ec6a2ffac..bb7c6b9296 100644
--- a/wicket-user-guide/src/main/asciidoc/advanced/advanced_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/advanced/advanced_2.adoc
@@ -9,15 +9,15 @@ public interface IRequestListener extends IClusterable
{
/**
- * Does invocation of this listener render the page.
- *
- * @return default {@code true}, i.e. a {@link RenderPageRequestHandler} is schedules after invocation
+ * Does invocation of this listener render the page.
+ *
+ * @return default {@code true}, i.e. a {@link RenderPageRequestHandler} is schedules after invocation
*/
default boolean rendersPage()
{
return true;
}
-
+
/**
* Called when a request is received.
*/
@@ -31,7 +31,7 @@ An example of a component that implements _IRequestListener_ can be seen in the
[source,java]
----
-public abstract class Link<T> extends AbstractLink implements IRequestListener ...
+public abstract class Link<T> extends AbstractLink implements IRequestListener ...
{
/**
* Called when a link is clicked.
@@ -40,7 +40,7 @@ public abstract class Link<T> extends AbstractLink implements IRequestListener .
/**
* THIS METHOD IS NOT PART OF THE WICKET API. DO NOT ATTEMPT TO OVERRIDE OR CALL IT.
- *
+ *
* Called when a link is clicked. The implementation of this method is currently to simply call
* onClick(), but this may be augmented in the future.
*/
@@ -55,13 +55,13 @@ public abstract class Link<T> extends AbstractLink implements IRequestListener .
Callback URLs can be generated with _Component_'s method _urlForListener(PageParameters)_ or with method _urlForListener(Behavior, PageParameters)_ if we are using a request listener on a component or behavior respectively (see the following example).
-Project _CallbackURLExample_ contains a behavior (class _OnChangeSingleChoiceBehavior_) that implements _org.apache.wicket.IRequestListener_ to update the model of an _AbstractSingleSelectChoice_ component when user changes the selected option (it provides the same functionality as _FormComponentUpdatingBehavior_).
+Project _CallbackURLExample_ contains a behavior (class _OnChangeSingleChoiceBehavior_) that implements _org.apache.wicket.IRequestListener_ to update the model of an _AbstractSingleSelectChoice_ component when user changes the selected option (it provides the same functionality as _FormComponentUpdatingBehavior_).
The following is the implementation of _onRequest()_ provided by _OnSelectionChangedNotifications_:
[source,java]
----
@Override
-public void onRequest() {
+public void onRequest() {
Request request = RequestCycle.get().getRequest();
IRequestParameters requestParameters = request.getRequestParameters();
StringValue choiceId = requestParameters.getParameterValue("choiceId");
@@ -79,26 +79,26 @@ Another interesting part of _OnChangeSingleChoiceBehavior_ is its method _onComp
@Override
public void onComponentTag(Component component, ComponentTag tag) {
super.onComponentTag(component, tag);
-
+
CharSequence callBackURL = getCallbackUrl();
String separatorChar = (callBackURL.toString().indexOf('?') > -1 ? "&" : "?");
-
+
String finalScript = "var isSelect = $(this).is('select');\n" +
- "var component;\n" +
+ "var component;\n" +
"if(isSelect)\n" +
" component = $(this);\n" +
"else \n" +
" component = $(this).find('input:radio:checked');\n" +
- "window.location.href='" + callBackURL + separatorChar +
+ "window.location.href='" + callBackURL + separatorChar +
"choiceId=' + " + "component.val()";
-
+
tag.put("onchange", finalScript);
}
----
The goal of _onComponentTag_ is to build an onchange handler that forces user's browser to move to the callback URL (modifing standard property window.location.href). Please note that we have appended the expected parameter (choiceId) to the URL retrieving its value with a JQuery selector suited for the current type of component (a drop-down menu or a radio group). Since we are using JQuery in our JavaScript code, the behavior comes also with method _renderHead_ that adds the bundled JQu [...]
-Method _getCallbackUrl()_ is used to generate the callback URL for our custom behavior:
+Method _getCallbackUrl()_ is used to generate the callback URL for our custom behavior:
[source,java]
----
@@ -115,7 +115,7 @@ public CharSequence getCallbackUrl() {
The home page of project _CallbackURLExample_ contains a _DropDownChoice_ and a _RadioChoice_ which use our custom behavior. There are also two labels to display the content of the models of the two components:
-image::../img/CallbackURLExample-screenshot.png[]
+image::./img/CallbackURLExample-screenshot.png[]
NOTE: Implementing interface _IRequestListener_ makes a behavior stateful because its callback URL is specific for a given instance of component.
diff --git a/wicket-user-guide/src/main/asciidoc/advanced/advanced_3.adoc b/wicket-user-guide/src/main/asciidoc/advanced/advanced_3.adoc
index 56e64aec13..d669f708eb 100644
--- a/wicket-user-guide/src/main/asciidoc/advanced/advanced_3.adoc
+++ b/wicket-user-guide/src/main/asciidoc/advanced/advanced_3.adoc
@@ -1,12 +1,12 @@
-Starting from version 1.5 Wicket offers an event-based infrastructure for inter-component communication. The infrastructure is based on two simple interfaces (both in package _org.apache.wicket.event_) : _IEventSource_ and _IEventSink_.
+Starting from version 1.5 Wicket offers an event-based infrastructure for inter-component communication. The infrastructure is based on two simple interfaces (both in package _org.apache.wicket.event_) : _IEventSource_ and _IEventSink_.
The first interface must be implemented by those entities that want to broadcast en event while the second interface must be implemented by those entities that want to receive a broadcast event.
The following entities already implement both these two interfaces (i.e. they can be either sender or receiver): _Component_, _Session_, _RequestCycle_ and _Application_.
_IEventSource_ exposes a single method named send which takes in input three parameters:
-* *sink*: an implementation of _IEventSink_ that will be the receiver of the event.
+* *sink*: an implementation of _IEventSink_ that will be the receiver of the event.
* *broadcast*: a _Broadcast_ enum which defines the broadcast method used to dispatch the event to the sink and to other entities such as sink children, sink containers, session object, application object and the current request cycle. It has four possible values:
|===
|*Value* | *Description*
@@ -25,16 +25,16 @@ Interface _IEventSink_ exposes callback method _onEvent(IEvent<?> event)_ which
----
@Override
public void onEvent(IEvent event) {
- //if the type of payload is MyPayloadClass perform some actions
+ //if the type of payload is MyPayloadClass perform some actions
if(event.getPayload() instanceof MyPayloadClass) {
//execute some business code.
}else{
//other business code
- }
+ }
}
----
Project _InterComponetsEventsExample_ provides a concrete example of sending an event to a component (named 'container in the middle') using all the available broadcast methods:
-image::../img/InterComponentsEventsExample-screenshot.png[]
+image::./img/InterComponentsEventsExample-screenshot.png[]
diff --git a/wicket-user-guide/src/main/asciidoc/advanced/advanced_5.adoc b/wicket-user-guide/src/main/asciidoc/advanced/advanced_5.adoc
index e35b30b1e4..bc5bad7e92 100644
--- a/wicket-user-guide/src/main/asciidoc/advanced/advanced_5.adoc
+++ b/wicket-user-guide/src/main/asciidoc/advanced/advanced_5.adoc
@@ -1,29 +1,29 @@
-JMX (Java Management Extensions) is the standard technology adopted in Java for managing and monitoring running applications or Java Virtual Machines. Wicket offers support for JMX through module wicket-jmx. In this paragraph we will see how we can connect to a Wicket application using JMX. In our example we will use JConsole as JMX client. This program is bundled with Java SE since version 5 and we can run it typing jconsole in our OS shell.
+JMX (Java Management Extensions) is the standard technology adopted in Java for managing and monitoring running applications or Java Virtual Machines. Wicket offers support for JMX through module wicket-jmx. In this paragraph we will see how we can connect to a Wicket application using JMX. In our example we will use JConsole as JMX client. This program is bundled with Java SE since version 5 and we can run it typing jconsole in our OS shell.
Once JConsole has started it will ask us to establish a new connection to a Java process, choosing between a local process or a remote one. In the following picture we have selected the process corresponding to the local instance of Jetty server we used to run one of our example projects:
-image::../img/JMX-new-connection.png[]
+image::./img/JMX-new-connection.png[]
After we have established a JMX connection, JConsole will show us the following set of tabs:
-image::../img/JMX-console.png[]
+image::./img/JMX-console.png[]
JMX exposes application-specific informations using special objects called MBeans (Manageable Beans), hence if we want to control our application we must open the corresponding tab. The MBeans containing the application's informations is named _org.apache.wicket.app.<filter/servlet name>_.
In our example we have used wicket.test as filter name for our application:
-image::../img/JMX-console2.png[]
+image::./img/JMX-console2.png[]
As we can see in the picture above, every MBean exposes a node containing its attributes and another node showing the possible operations that can be performed on the object. In the case of a Wicket application the available operations are clearMarkupCache and clearLocalizerCache:
-image::../img/JMX-console3.png[]
+image::./img/JMX-console3.png[]
With these two operations we can force Wicket to clear the internal caches used to load components markup and resource bundles. This can be particularly useful if we have our application running in DEPLOYMENT mode and we want to publish minor fixes for markup or bundle files (like spelling or typo corrections) without restarting the entire application. Without cleaning these two caches Wicket would continue to use cached values ignoring any change made to markup or bundle files.
Some of the exposed properties are editable, hence we can tune their values while the application is running. For example if we look at the properties of _ApplicationSettings_ we can set the maximum size allowed for an upload modifying the attribute DefaultMaximumUploadSize:
-image::../img/JMX-console4.png[]
+image::./img/JMX-console4.png[]
diff --git a/wicket-user-guide/src/main/asciidoc/ajax/ajax_2.adoc b/wicket-user-guide/src/main/asciidoc/ajax/ajax_2.adoc
index f188819b44..43fe6855b5 100644
--- a/wicket-user-guide/src/main/asciidoc/ajax/ajax_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/ajax/ajax_2.adoc
@@ -1,7 +1,7 @@
-Wicket distribution comes with a number of built-in AJAX components ready to be used. Some of them are the ajaxified version of common components like links and buttons, while others are AJAX-specific components.
+Wicket distribution comes with a number of built-in AJAX components ready to be used. Some of them are the ajaxified version of common components like links and buttons, while others are AJAX-specific components.
AJAX components are not different from any other component seen so far and they don't require any additional configuration to be used. As we will shortly see, switching from a classic link or button to the ajaxified version is just a matter of prepending “Ajax” to the component class name.
@@ -9,7 +9,7 @@ This paragraph provides an overview of what we can find in Wicket to start writi
=== Links and buttons
-In the previous paragraph we have already introduced component AjaxLink. Wicket provides also the ajaxified versions of submitting components SubmitLink and Button which are simply called AjaxSubmitLink and AjaxButton. These components come with a version of methods onSubmit, onError and onAfterSubmit that takes in input also an instance of _AjaxRequestTarget_.
+In the previous paragraph we have already introduced component AjaxLink. Wicket provides also the ajaxified versions of submitting components SubmitLink and Button which are simply called AjaxSubmitLink and AjaxButton. These components come with a version of methods onSubmit, onError and onAfterSubmit that takes in input also an instance of _AjaxRequestTarget_.
Both components are in package _org.apache.wicket.ajax.markup.html.form_.
@@ -26,29 +26,29 @@ Class _org.apache.wicket.ajax.markup.html.form.AjaxCheckBox_ is a checkbox compo
An editable label is a special label that can be edited by the user when she/he clicks on it. Wicket ships three different implementations for this component (all inside package _org.apache.wicket.extensions.ajax.markup.html_):
* *AjaxEditableLabel*: it's a basic version of editable label. User can edit the content of the label with a text field. This is also the base class for the other two editable labels.
-* *AjaxEditableMultiLineLabel*: this label supports multi-line values and uses a text area as editor component.
+* *AjaxEditableMultiLineLabel*: this label supports multi-line values and uses a text area as editor component.
* *AjaxEditableChoiceLabel*: this label uses a drop-down menu to edit its value.
Base component AjaxEditableLabel exposes the following set of AJAX-aware methods that can be overriden:
-* *onEdit(AjaxRequestTarget target)*: called when user clicks on component. The default implementation shows the component used to edit the value of the label.
+* *onEdit(AjaxRequestTarget target)*: called when user clicks on component. The default implementation shows the component used to edit the value of the label.
* *onSubmit(AjaxRequestTarget target)*: called when the value has been successfully updated with the new input.
* *onError(AjaxRequestTarget target)*: called when the new inserted input has failed validation.
-* *onCancel(AjaxRequestTarget target)*: called when user has exited from editing mode pressing escape key. The default implementation brings back the label to its initial state hiding the editor component.
+* *onCancel(AjaxRequestTarget target)*: called when user has exited from editing mode pressing escape key. The default implementation brings back the label to its initial state hiding the editor component.
Wicket module wicket-examples contains page class _EditableLabelPage.java_ which shows all these three components together. You can see this page in action on {wicket_examples_url}/ajax/editable-label[examples site]:
-image::../img/edit-label-example-screenshot.png[]
+image::./img/edit-label-example-screenshot.png[]
=== Autocomplete text field
-On Internet we can find many examples of text fields that display a list of suggestions (or options) while the user types a text inside them. This feature is known as autocomplete functionality.
+On Internet we can find many examples of text fields that display a list of suggestions (or options) while the user types a text inside them. This feature is known as autocomplete functionality.
-Wicket offers an out-of-the-box implementation of an autocomplete text field with component _org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField_.
+Wicket offers an out-of-the-box implementation of an autocomplete text field with component _org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField_.
When using AutoCompleteTextField we are required to implement its abstract method getChoices(String input) where the input parameter is the current input of the component. This method returns an iterator over the suggestions that will be displayed as a drop-down menu:
-image::../img/autocomplete-example-screenshot.png[]
+image::./img/autocomplete-example-screenshot.png[]
Suggestions are rendered using a render which implements interface _IAutoCompleteRenderer_. The default implementation simply calls toString() on each suggestion object. If we need to work with a custom render we can specify it via component constructor.
@@ -59,14 +59,14 @@ One of the most interesting parameter we can specify for _AutoCompleteTextField_
[source,java]
----
AutoCompleteSettings settings = new AutoCompleteSettings();
-//set throttle to 400 ms: component will wait 400ms before displaying the options
+//set throttle to 400 ms: component will wait 400ms before displaying the options
settings.setThrottleDelay(400);
-//...
+//...
AutoCompleteTextField field = new AutoCompleteTextField<T>("field", model) {
@Override
protected Iterator getChoices(String arg0) {
- //return an iterator over the options
+ //return an iterator over the options
}
};
----
@@ -77,7 +77,7 @@ Wicket module wicket-examples contains page class _AutoCompletePagePage.java_ wh
Class _org.apache.wicket.extensions.ajax.markup.html.modal.ModalDialog_ is an implementation of a http://en.wikipedia.org/wiki/Modal_dialog[modal dialog] based on AJAX:
-image::../img/modal-dialog-example-screenshot.png[]
+image::./img/modal-dialog-example-screenshot.png[]
The content of a modal dialog is another component. The id of this component used as content must be _ModalDialog#CONTENT_ID_.
@@ -102,20 +102,20 @@ public HomePage(final PageParameters parameters) {
modal.add(new DefaultTheme());
modal.closeOnClick();
Label label = new Label(ModalDialog.CONTENT_ID, "I'm a modal dialog!");
-
+
modal.setContent(label);
-
+
add(modal);
add(new AjaxLink<Void>("open") {
@Override
public void onClick(AjaxRequestTarget target) {
- modal.open(target);
- }
+ modal.open(target);
+ }
});
}
----
-Just like any other component also _ModalDialog_ must be added to a markup tag, like we did in our example using a <div> tag. Wicket will automatically hide the content of this tag in the final markup, as long as the dialog is not opened.
+Just like any other component also _ModalDialog_ must be added to a markup tag, like we did in our example using a <div> tag. Wicket will automatically hide the content of this tag in the final markup, as long as the dialog is not opened.
This component does not provide any styling by itself, so you have can add a
_DefaultTheme_ to this component if aren't styling these CSS classes by yourself.
@@ -125,17 +125,17 @@ The modal dialog can be closed from code using its method _close(AjaxRequestTarg
Class _org.apache.wicket.extensions.markup.html.repeater.tree.AbstractTree_ is the base class of another family of repeaters called tree repeaters and designed to display a data hierarchy as a tree, resembling the behavior and the look & feel of desktop tree components. A classic example of tree component on desktop is the tree used by nearly all file managers to navigate file system:
-image::../img/file-system-trees.png[]
+image::./img/file-system-trees.png[]
-Because of their highly interactive nature, tree repeaters are implemented as AJAX components, meaning that they are updated via AJAX when we expand or collapse their nodes.
+Because of their highly interactive nature, tree repeaters are implemented as AJAX components, meaning that they are updated via AJAX when we expand or collapse their nodes.
-The basic implementation of a tree repeater shipped with Wicket is component _NestedTree_. In order to use a tree repeater we must provide an implementation of interface _ITreeProvider_ which is in charge of returning the nodes that compose the tree.
+The basic implementation of a tree repeater shipped with Wicket is component _NestedTree_. In order to use a tree repeater we must provide an implementation of interface _ITreeProvider_ which is in charge of returning the nodes that compose the tree.
-Wicket comes with a built-in implementation of ITreeProvider called TreeModelProvider that works with the same tree model and nodes used by Swing component _javax.swing.JTree_. These Swing entities should be familiar to you if you have previously worked with the old tree repeaters (components _Tree_ and _TreeTable_) that have been deprecated with Wicket 6 and that are strongly dependent on Swing-based model and nodes. _TreeModelProvider_ can be used to migrate your code to the new tree r [...]
+Wicket comes with a built-in implementation of ITreeProvider called TreeModelProvider that works with the same tree model and nodes used by Swing component _javax.swing.JTree_. These Swing entities should be familiar to you if you have previously worked with the old tree repeaters (components _Tree_ and _TreeTable_) that have been deprecated with Wicket 6 and that are strongly dependent on Swing-based model and nodes. _TreeModelProvider_ can be used to migrate your code to the new tree r [...]
In the next example (project _CheckBoxAjaxTree_) we will build a tree that displays some of the main cities of three European countries: Italy, Germany and France. The cities are sub-nodes of a main node representing the relative county. The nodes of the final tree will be also selectable with a checkbox control. The whole tree will have the classic look & feel of Windows XP. This is how our tree will look like:
-image::../img/AJAX-tree-repeater.png[]
+image::./img/AJAX-tree-repeater.png[]
We will start to explore the code of this example from the home page. The first portion of code we will see is where we build the nodes and the _TreeModelProvider_ for the three. As tree node we will use Swing class _javax.swing.tree.DefaultMutableTreeNode_:
@@ -145,13 +145,13 @@ public class HomePage extends WebPage {
public HomePage(final PageParameters parameters) {
super(parameters);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Cities of Europe");
-
+
addNodes(addNodes(root, "Italy"), "Rome", "Venice", "Milan", "Florence");
addNodes(addNodes(root, "Germany"),"Stuttgart","Munich", "Berlin","Dusseldorf", "Dresden");
addNodes(addNodes(root, "France"), "Paris","Toulouse", "Strasbourg","Bordeaux", "Lyon");
-
+
DefaultTreeModel treeModel = new DefaultTreeModel(root);
- TreeModelProvider<DefaultMutableTreeNode> modelProvider = new
+ TreeModelProvider<DefaultMutableTreeNode> modelProvider = new
TreeModelProvider<DefaultMutableTreeNode>( treeModel ){
@Override
public IModel<DefaultMutableTreeNode> model(DefaultMutableTreeNode object){
@@ -168,7 +168,7 @@ Scrolling down the code we can see how the tree component is instantiated and co
[source,java]
----
//Continued from previous snippet...
- NestedTree<DefaultMutableTreeNode> tree = new NestedTree<DefaultMutableTreeNode>("tree",
+ NestedTree<DefaultMutableTreeNode> tree = new NestedTree<DefaultMutableTreeNode>("tree",
modelProvider)
{
@@ -180,7 +180,7 @@ Scrolling down the code we can see how the tree component is instantiated and co
};
//select Windows theme
tree.add(new WindowsTheme());
-
+
add(tree);
}
//implementation of addNodes
@@ -188,7 +188,7 @@ Scrolling down the code we can see how the tree component is instantiated and co
}
----
-To use tree repeaters we must implement their abstract method _newContentComponent_ which is called internally by base class _AbstractTree_ when a new node must be built. As content component we have used built-in class _CheckedFolder_ which combines a _Folder_ component with a _CheckBox_ form control.
+To use tree repeaters we must implement their abstract method _newContentComponent_ which is called internally by base class _AbstractTree_ when a new node must be built. As content component we have used built-in class _CheckedFolder_ which combines a _Folder_ component with a _CheckBox_ form control.
The final step before adding the tree to its page is to apply a theme to it. Wicket comes with two behaviors, WindowsTheme and HumanTheme, which correspond to the classic Windows XP theme and to the Human theme from Ubuntu.
@@ -203,7 +203,7 @@ The first goal (keeping track of checked node) can be accomplished building a cu
For the second goal (auto select/unselect children and ancestor nodes) we can use _CheckedFolder_'s callback method onUpdate(AjaxRequestTarget) that is invoked after a checkbox is clicked and its value has been updated. Overriding this method we can handle user click adding/removing nodes to/from the Java Set.
-Following this implementation plan we can start coding our custom _CheckedFolder_ (named _AutocheckedFolder_):
+Following this implementation plan we can start coding our custom _CheckedFolder_ (named _AutocheckedFolder_):
[source,java]
----
@@ -212,28 +212,28 @@ public class AutocheckedFolder<T> extends CheckedFolder<T> {
private ITreeProvider<T> treeProvider;
private IModel<Set<T>> checkedNodes;
private IModel<Boolean> checkboxModel;
-
- public AutocheckedFolder(String id, AbstractTree<T> tree,
+
+ public AutocheckedFolder(String id, AbstractTree<T> tree,
IModel<T> model, IModel<Set<T>> checkedNodes) {
- super(id, tree, model);
+ super(id, tree, model);
this.treeProvider = tree.getProvider();
- this.checkedNodes = checkedNodes;
+ this.checkedNodes = checkedNodes;
}
-
+
@Override
protected IModel<Boolean> newCheckBoxModel(IModel<T> model) {
checkboxModel = new CheckModel();
return checkboxModel;
}
-
+
@Override
protected void onUpdate(AjaxRequestTarget target) {
super.onUpdate(target);
T node = getModelObject();
boolean nodeChecked = checkboxModel.getObject();
-
- addRemoveSubNodes(node, nodeChecked);
- addRemoveAncestorNodes(node, nodeChecked);
+
+ addRemoveSubNodes(node, nodeChecked);
+ addRemoveAncestorNodes(node, nodeChecked);
}
class CheckModel extends AbstractCheckBoxModel{
@@ -250,20 +250,20 @@ public class AutocheckedFolder<T> extends CheckedFolder<T> {
@Override
public void unselect() {
checkedNodes.getObject().remove(getModelObject());
- }
+ }
}
}
----
-The constructor of this new component takes in input a further parameter which is the set containing checked nodes.
+The constructor of this new component takes in input a further parameter which is the set containing checked nodes.
-Class CheckModel is the custom model we have implemented for checkbox control. As base class for this model we have used _AbstractCheckBoxModel_ which is provided to implement custom models for checkbox controls.
+Class CheckModel is the custom model we have implemented for checkbox control. As base class for this model we have used _AbstractCheckBoxModel_ which is provided to implement custom models for checkbox controls.
Methods _addRemoveSubNodes_ and _addRemoveAncestorNodes_ are called to automatically add/remove children and ancestor nodes to/from the current Set. Their implementation is mainly focused on the navigation of tree nodes and it heavily depends on the internal implementation of the tree, so we won't dwell on their code.
-Now we are just one step away from completing our tree as we still have to find a way to update the checked status of both children and ancestors nodes on client side. Although we could easily accomplish this task by simply refreshing the whole tree via AJAX, we would like to find a better and more performant solution for this task.
+Now we are just one step away from completing our tree as we still have to find a way to update the checked status of both children and ancestors nodes on client side. Although we could easily accomplish this task by simply refreshing the whole tree via AJAX, we would like to find a better and more performant solution for this task.
-When we modify the checked status of a node we don't expand/collapse any node of the three so we can simply update the desired checkboxes rather than updating the entire tree component. This alternative approach could lead to a more responsive interface and to a strong reduction of bandwidth consumption.
+When we modify the checked status of a node we don't expand/collapse any node of the three so we can simply update the desired checkboxes rather than updating the entire tree component. This alternative approach could lead to a more responsive interface and to a strong reduction of bandwidth consumption.
With the help of JQuery we can code a couple of JavaScript functions that can be used to check/ uncheck all the children and ancestors of a given node. Then, we can append these functions to the current _AjaxRequest_ at the end of method onUpdate:
@@ -274,18 +274,18 @@ With the help of JQuery we can code a couple of JavaScript functions that can be
super.onUpdate(target);
T node = getModelObject();
boolean nodeChecked = checkboxModel.getObject();
-
- addRemoveSubNodes(node, nodeChecked);
- addRemoveAncestorNodes(node, nodeChecked);
- updateNodeOnClientSide(target, nodeChecked);
+
+ addRemoveSubNodes(node, nodeChecked);
+ addRemoveAncestorNodes(node, nodeChecked);
+ updateNodeOnClientSide(target, nodeChecked);
}
protected void updateNodeOnClientSide(AjaxRequestTarget target,
boolean nodeChecked) {
- target.appendJavaScript(";CheckAncestorsAndChildren.checkChildren('" + getMarkupId() +
+ target.appendJavaScript(";CheckAncestorsAndChildren.checkChildren('" + getMarkupId() +
"'," + nodeChecked + ");");
-
- target.appendJavaScript(";CheckAncestorsAndChildren.checkAncestors('" + getMarkupId() +
+
+ target.appendJavaScript(";CheckAncestorsAndChildren.checkAncestors('" + getMarkupId() +
"'," + nodeChecked + ");");
}
----
@@ -296,7 +296,7 @@ The JavaScript code can be found inside file autocheckedFolder.js which is added
----
@Override
public void renderHead(IHeaderResponse response) {
- PackageResourceReference scriptFile = new PackageResourceReference(this.getClass(),
+ PackageResourceReference scriptFile = new PackageResourceReference(this.getClass(),
"autocheckedFolder.js");
response.render(JavaScriptHeaderItem.forReference(scriptFile));
}
@@ -304,7 +304,7 @@ public void renderHead(IHeaderResponse response) {
=== Working with hidden components
-When a component is not visible its markup and the related id attribute are not rendered in the final page, hence it can not be updated via AJAX. To overcome this problem we must use Component's method _setOutputMarkupPlaceholderTag(true)_ which has the effect of rendering a hidden <span> tag containing the markup id of the hidden component:
+When a component is not visible its markup and the related id attribute are not rendered in the final page, hence it can not be updated via AJAX. To overcome this problem we must use Component's method _setOutputMarkupPlaceholderTag(true)_ which has the effect of rendering a hidden <span> tag containing the markup id of the hidden component:
[source,java]
----
@@ -321,7 +321,7 @@ new AjaxLink<Void>("ajaxLink"){
//turn label to visible
label.setVisible(true);
target.add(label);
- }
+ }
};
----
diff --git a/wicket-user-guide/src/main/asciidoc/ajax/ajax_6.adoc b/wicket-user-guide/src/main/asciidoc/ajax/ajax_6.adoc
index fd0f63cdfb..a0e9160d07 100644
--- a/wicket-user-guide/src/main/asciidoc/ajax/ajax_6.adoc
+++ b/wicket-user-guide/src/main/asciidoc/ajax/ajax_6.adoc
@@ -7,11 +7,11 @@ Displaying an activity indicator is a nice way to notify user that an AJAX reque
The listener should execute some JavaScript code to disable a given component when the component it is attached to is about to make an AJAX call. Then, when the AJAX request has been completed, the listener should bring back the disabled component to an active state.
-When a component is disabled it must be clear to user that an AJAX request is running and that he/she must wait for it to complete. To achieve this result we want to disable a given component covering it with a semi-transparent overlay area with an activity indicator in the middle.
+When a component is disabled it must be clear to user that an AJAX request is running and that he/she must wait for it to complete. To achieve this result we want to disable a given component covering it with a semi-transparent overlay area with an activity indicator in the middle.
The final result will look like this:
-image::../img/custom-ajax-call-listener.png[]
+image::./img/custom-ajax-call-listener.png[]
=== How to implement the listener
@@ -19,7 +19,7 @@ The listener will implement methods _getBeforeHandler_ and _getAfterHandler_: th
To move and resize the overlay area we will use another module from http://jqueryui.com/position/[JQueryUI library] that allows us to position DOM elements on our page relative to another element.
-So our listener will depend on four static resources: the JQuery library, the position module of JQuery UI, the custom code used to move the overlay <div> and the picture used as activity indicator. Except for the activity indicator, all these resources must be added to page header section in order to be used.
+So our listener will depend on four static resources: the JQuery library, the position module of JQuery UI, the custom code used to move the overlay <div> and the picture used as activity indicator. Except for the activity indicator, all these resources must be added to page header section in order to be used.
Ajax call listeners can contribute to header section by simply implementing interface _IComponentAwareHeaderContributor_. Wicket provides adapter class _AjaxCallListener_ that implements both _IAjaxCallListener_ and _IComponentAwareHeaderContributor_. We will use this class as base class for our listener.
@@ -33,26 +33,26 @@ DisableComponentListener = {
disableElement: function(elementId, activeIconUrl){
var hiderId = elementId + "-disable-layer";
var indicatorId = elementId + "-indicator-picture";
-
+
elementId = "#" + elementId;
//create the overlay <div>
- $(elementId).after('<div id="' + hiderId
+ $(elementId).after('<div id="' + hiderId
+ '" style="position:absolute;">'
+ '<img id="' + indicatorId + '" src="' + activeIconUrl + '"/>'
+ '</div>');
-
+
hiderId = "#" + hiderId;
//set the style properties of the overlay <div>
- $(hiderId).css('opacity', '0.8');
+ $(hiderId).css('opacity', '0.8');
$(hiderId).css('text-align', 'center');
$(hiderId).css('background-color', 'WhiteSmoke');
$(hiderId).css('border', '1px solid DarkGray');
//set the dimention of the overlay <div>
$(hiderId).width($(elementId).outerWidth());
- $(hiderId).height($(elementId).outerHeight());
- //positioning the overlay <div> on the component that must be disabled.
+ $(hiderId).height($(elementId).outerHeight());
+ //positioning the overlay <div> on the component that must be disabled.
$(hiderId).position({of: $(elementId),at: 'top left', my: 'top left'});
-
+
//positioning the activity indicator in the middle of the overlay <div>
$("#" + indicatorId).position({of: $(hiderId), at: 'center center',
my: 'center center'});
@@ -80,43 +80,43 @@ The code of our custom listener is the following:
[source,java]
----
public class DisableComponentListener extends AjaxCallListener {
- private static PackageResourceReference customScriptReference = new
+ private static PackageResourceReference customScriptReference = new
PackageResourceReference(DisableComponentListener.class, "moveHiderAndIndicator.js");
-
- private static PackageResourceReference jqueryUiPositionRef = new
+
+ private static PackageResourceReference jqueryUiPositionRef = new
PackageResourceReference(DisableComponentListener.class, "jquery-ui-position.min.js");
-
- private static PackageResourceReference indicatorReference =
+
+ private static PackageResourceReference indicatorReference =
new PackageResourceReference(DisableComponentListener.class, "ajax-loader.gif");
-
+
private Component targetComponent;
-
+
public DisableComponentListener(Component targetComponent){
this.targetComponent = targetComponent;
}
-
+
@Override
- public CharSequence getBeforeHandler(Component component) {
+ public CharSequence getBeforeHandler(Component component) {
CharSequence indicatorUrl = getIndicatorUrl(component);
- return ";DisableComponentListener.disableElement('" + targetComponent.getMarkupId()
+ return ";DisableComponentListener.disableElement('" + targetComponent.getMarkupId()
+ "'," + "'" + indicatorUrl + "');";
}
@Override
public CharSequence getCompleteHandler(Component component) {
- return ";DisableComponentListener.hideComponent('"
+ return ";DisableComponentListener.hideComponent('"
+ targetComponent.getMarkupId() + "');";
}
-
+
protected CharSequence getIndicatorUrl(Component component) {
return component.urlFor(indicatorReference, null);
}
-
+
@Override
- public void renderHead(Component component, IHeaderResponse response) {
- ResourceReference jqueryReference =
+ public void renderHead(Component component, IHeaderResponse response) {
+ ResourceReference jqueryReference =
Application.get().getJavaScriptLibrarySettings().getJQueryReference();
- response.render(JavaScriptHeaderItem.forReference(jqueryReference));
+ response.render(JavaScriptHeaderItem.forReference(jqueryReference));
response.render(JavaScriptHeaderItem.forReference(jqueryUiPositionRef));
response.render(JavaScriptHeaderItem.forReference(customScriptReference) );
}
@@ -142,7 +142,7 @@ new AjaxButton("ajaxButton"){
=== Global listeners
-So far we have seen how to use an AJAX call listener to track the AJAX activity of a single component. In addition to these kinds of listeners, Wicket provides also global listeners which are triggered for any AJAX request sent from a page.
+So far we have seen how to use an AJAX call listener to track the AJAX activity of a single component. In addition to these kinds of listeners, Wicket provides also global listeners which are triggered for any AJAX request sent from a page.
Global AJAX call events are handled with JavaScript. We can register a callback function for a specific event of the AJAX call lifecycle with function _Wicket.Event.subscribe('<eventName>', <callback Function>)_. The first parameter of this function is the name of the event we want to handle. The possible names are:
@@ -154,24 +154,24 @@ Global AJAX call events are handled with JavaScript. We can register a callback
* '/ajax/call/failure': called if the AJAX call has returned with a failure.
* '/ajax/call/complete': called when the AJAX call has completed.
* '/ajax/call/done': called when the AJAX call is done.
-* '/dom/node/removing': called when a component is about to be removed via AJAX. This happens when component markup is updated via AJAX (i.e. the component itself or one of its containers has been added to _AjaxRequestTarget_)
+* '/dom/node/removing': called when a component is about to be removed via AJAX. This happens when component markup is updated via AJAX (i.e. the component itself or one of its containers has been added to _AjaxRequestTarget_)
* '/dom/node/added': called when a component has been added via AJAX. Just like '/dom/node/removing', this event is triggered when a component is added to _AjaxRequestTarget_.
-The callback function takes in input the following parameters: attrs, jqXHR, textStatus, jqEvent and errorThrown. The first three parameters are the same seen before with _IAjaxCallListener_ while jqEvent is an event internally fired by Wicket. The last parameter errorThrown indicates if an error has occurred during the AJAX call.
+The callback function takes in input the following parameters: attrs, jqXHR, textStatus, jqEvent and errorThrown. The first three parameters are the same seen before with _IAjaxCallListener_ while jqEvent is an event internally fired by Wicket. The last parameter errorThrown indicates if an error has occurred during the AJAX call.
-To see a basic example of use of a global AJAX call listener, let's go back to our custom datepicker created in
-<<_an_example_of_integration_with_javascript,chapter 19>>. When we built it we didn't think about a possible use of the component with AJAX. When a complex component like our datepicker is refreshed via AJAX, the following two side effects can occur:
+To see a basic example of use of a global AJAX call listener, let's go back to our custom datepicker created in
+<<_an_example_of_integration_with_javascript,chapter 19>>. When we built it we didn't think about a possible use of the component with AJAX. When a complex component like our datepicker is refreshed via AJAX, the following two side effects can occur:
* After been refreshed, the component loses every JavaScript handler set on it. This is not a problem for our datepicker as it sets a new JQuery datepicker every time is rendered (inside method renderHead).
* The markup previously created with JavaScript is not removed. For our datepicker this means that the icon used to open the calendar won't be removed while a new one will be added each time the component is refreshed.
-To solve the second unwanted side effect we can register a global AJAX call listener that completely removes the datepicker functionality from our component before it is removed due to an AJAX refresh (which fires event '/dom/node/removing').
+To solve the second unwanted side effect we can register a global AJAX call listener that completely removes the datepicker functionality from our component before it is removed due to an AJAX refresh (which fires event '/dom/node/removing').
Project _CustomDatepickerAjax_ contains a new version of our datepicker which adds to its JavaScript file JQDatePicker.js the code needed to register a callback function that gets rid of the JQuery datepicker before the component is removed from the DOM:
[source,java]
----
-Wicket.Event.subscribe('/dom/node/removing',
+Wicket.Event.subscribe('/dom/node/removing',
function(jqEvent, attributes, jqXHR, errorThrown, textStatus) {
var componentId = '#' + attributes['id'];
if($(componentId).datepicker !== undefined)
diff --git a/wicket-user-guide/src/main/asciidoc/bestpractices/bestpractices_16.adoc b/wicket-user-guide/src/main/asciidoc/bestpractices/bestpractices_16.adoc
index e15ba17479..9851d9605c 100644
--- a/wicket-user-guide/src/main/asciidoc/bestpractices/bestpractices_16.adoc
+++ b/wicket-user-guide/src/main/asciidoc/bestpractices/bestpractices_16.adoc
@@ -3,5 +3,5 @@
It is a widespread opinion that Wicket has a bad documentation. This argument is just partly correct. There are a lot of code samples and snippets which can be used as code templates. Furthermore, there is a big community that answers complex questions very quickly. In Wicket it is very hard to document everything, because nearly everything is extensible and replaceable. If a component is not completely suitable, you will extend or replace it. Working with Wicket means permanently naviga [...]
-image::../img/validator-type-hierachy.png[]
+image::./img/validator-type-hierachy.png[]
diff --git a/wicket-user-guide/src/main/asciidoc/bestpractices/bestpractices_5.adoc b/wicket-user-guide/src/main/asciidoc/bestpractices/bestpractices_5.adoc
index 31e297aa2a..a8585a8a72 100644
--- a/wicket-user-guide/src/main/asciidoc/bestpractices/bestpractices_5.adoc
+++ b/wicket-user-guide/src/main/asciidoc/bestpractices/bestpractices_5.adoc
@@ -21,7 +21,7 @@ This approach is error-prone and fragile, because we always have to pay attentio
The solution is the Hollywood principle: "Don't call us, we'll call you". Take a look at the following diagram illustrating an application flow with some calls. We avoid three calls through the http://en.wikipedia.org/wiki/Hollywood_Principle[Hollywood-Principle] and we just have to instantiate the _LoginBoxPanel_.
-image::../img/login_calls_hollywood.png[]
+image::./img/login_calls_hollywood.png[]
*Listing 7:*
diff --git a/wicket-user-guide/src/main/asciidoc/componentLifecycle/componentLifecycle_1.adoc b/wicket-user-guide/src/main/asciidoc/componentLifecycle/componentLifecycle_1.adoc
index 45df71c6bd..98eca62a01 100644
--- a/wicket-user-guide/src/main/asciidoc/componentLifecycle/componentLifecycle_1.adoc
+++ b/wicket-user-guide/src/main/asciidoc/componentLifecycle/componentLifecycle_1.adoc
@@ -10,12 +10,12 @@ During its life a Wicket component goes through the following stages:
The following picture shows the state diagram of component lifecycle:
-image::../img/component-lifecycle.png[]
+image::./img/component-lifecycle.png[]
Once a component has been removed it could be added again to a container, but the initialization stage won't be executed again - it is easier to just create a new component instance instead.
NOTE: If you read the JavaDoc of class _Component_ you will find a more detailed description of component lifecycle.
-However this description introduces some advanced topics we didn't covered yet hence, to avoid confusion, in this chapter some details have been omitted and they will be covered later in the next chapters.
+However this description introduces some advanced topics we didn't covered yet hence, to avoid confusion, in this chapter some details have been omitted and they will be covered later in the next chapters.
For now you can consider just the simplified version of the lifecycle described above.
diff --git a/wicket-user-guide/src/main/asciidoc/forms2/forms2_11.adoc b/wicket-user-guide/src/main/asciidoc/forms2/forms2_11.adoc
index bf3f93fa6f..8854eff957 100644
--- a/wicket-user-guide/src/main/asciidoc/forms2/forms2_11.adoc
+++ b/wicket-user-guide/src/main/asciidoc/forms2/forms2_11.adoc
@@ -3,7 +3,7 @@
In this paragraph we will see which components can be used to handle HTML radio buttons and checkboxes. Both these input elements are usually grouped together to display a list of possible choices:
-image::../img/choice-form-screenshot.png[]
+image::./img/choice-form-screenshot.png[]
A check box can be used as single component to set a boolean property. For this purpose Wicket provides the _org.apache.wicket.markup.html.form.CheckBox_ component which must be attached to <input type="checkbox"/> tag. In the next example (project SingleCheckBox) we will consider a form similar to the one used in <<modelsforms.adoc#_component_dropdownchoice,paragraph 11.5>> to edit a Person object, but with an additional checkbox to let the user decide if she wants to subscribe to our m [...]
@@ -87,7 +87,7 @@ public HomePage(final PageParameters parameters) {
Please note that the checkbox will be initially selected because we have set to true the subscribe flag during the model object creation (with instruction registrtionInfo.setSubscribeList(true)):
-image::../img/subscribe-checkbox-set.png[]
+image::./img/subscribe-checkbox-set.png[]
=== Working with grouped checkboxes
@@ -113,7 +113,7 @@ form.add(new CheckBoxMultipleChoice("checkGroup", new ListModel<String>(new
*Screenshot:*
-image::../img/grouped-checkbox.png[]
+image::./img/grouped-checkbox.png[]
This component can be attached to a <div> tag or to a <span> tag. No specific content is required for this tag as it will be populated with the actual checkboxes. Since this component allows multiple selection, its model object is a list. In the example above we have used model class _org.apache.wicket.model.util.ListModel_ which is specifically designed to wrap a List object.
@@ -145,13 +145,13 @@ form.add(new CheckBoxMultipleChoice("checkGroup", new ListModel<String>(new Arra
*Screenshot:*
-image::../img/grouped-checkbox2.png[]
+image::./img/grouped-checkbox2.png[]
=== How to implement a "Select all" checkbox
A nice feature we can offer to users when we have a group of checkboxes is a “special” checkbox which selects/unselects all the other options of the group:
-image::../img/select-all-checkbox.png[]
+image::./img/select-all-checkbox.png[]
Wicket comes with a couple of utility components that make it easy to implement such a feature. They are CheckboxMultipleChoiceSelector and CheckBoxSelector classes, both inside package _org.apache.wicket.markup.html.form_. The difference between these two components is that the first works with an instance of CheckBoxMultipleChoice while the second takes in input a list of CheckBox objects:
@@ -193,6 +193,6 @@ form.add(new RadioChoice("radioGroup", Model.of(""), fruits));
*Screenshot:*
-image::../img/grouped-radiobutton.png[]
+image::./img/grouped-radiobutton.png[]
Just like CheckBoxMultipleChoice, this component provides the setPrefix and setSuffix methods to configure the prefix and suffix for our options and it supports IChoiceRender as well.
diff --git a/wicket-user-guide/src/main/asciidoc/forms2/forms2_12.adoc b/wicket-user-guide/src/main/asciidoc/forms2/forms2_12.adoc
index a29f14d39c..f798e3d885 100644
--- a/wicket-user-guide/src/main/asciidoc/forms2/forms2_12.adoc
+++ b/wicket-user-guide/src/main/asciidoc/forms2/forms2_12.adoc
@@ -3,9 +3,9 @@
Checkboxes work well when we have a small amount of options to display, but they quickly become chaotic as the number of options increases. To overcome this limit we can use the <select> tag switching it to multiple-choice mode with attribute multiple="multiple"
-image::../img/list-multiple-choices.png[]
+image::./img/list-multiple-choices.png[]
-Now the user can select multiple options by holding down Ctrl key (or Command key for Mac) and selecting them.
+Now the user can select multiple options by holding down Ctrl key (or Command key for Mac) and selecting them.
To work with multiple choice list Wicket provides the _org.apache.wicket.markup.html.form.ListMultipleChoice_ component:
@@ -23,23 +23,23 @@ To work with multiple choice list Wicket provides the _org.apache.wicket.markup.
[source,java]
----
-List<String> fruits = Arrays.asList("apple", "strawberry", "watermelon");
+List<String> fruits = Arrays.asList("apple", "strawberry", "watermelon");
form.add(new ListMultipleChoice("fruits", new ListModel<String>(new ArrayList<String>()), fruits));
----
*Screenshot:*
-image::../img/list-multiple-choices2.png[]
+image::./img/list-multiple-choices2.png[]
-This component must be bound to a <select> tag but the attribute multiple="multiple" is not required as it will automatically be added by the component.
+This component must be bound to a <select> tag but the attribute multiple="multiple" is not required as it will automatically be added by the component.
The number of visible rows can be set with the setMaxRows(int maxRows) method.
=== Component Palette
-While multiple choice list solves the problem of handling a big number of multiple choices, it is not much intuitive for end users. That's why desktop GUIs have introduced a more complex component which can be generally referred to as multi select transfer component (it doesn't have an actual official name):
+While multiple choice list solves the problem of handling a big number of multiple choices, it is not much intuitive for end users. That's why desktop GUIs have introduced a more complex component which can be generally referred to as multi select transfer component (it doesn't have an actual official name):
-image::../img/multi-select-transfer-component.png[]
+image::./img/multi-select-transfer-component.png[]
This kind of component is composed by two multiple-choice lists, one on the left displaying the available options and the other one on the right displaying the selected options. User can move options from a list to another by double clicking on them or using the buttons placed between the two list.
@@ -67,17 +67,17 @@ Person bob = new Person("Bob", "Smith");
Person jill = new Person("Jill", "Smith");
Person andrea = new Person("Andrea", "Smith");
-List<Person> theSmiths = Arrays.asList(john, bob, jill, andrea);
-ChoiceRenderer render = new ChoiceRenderer("name");
+List<Person> theSmiths = Arrays.asList(john, bob, jill, andrea);
+ChoiceRenderer render = new ChoiceRenderer("name");
form.add(new Palette("palette", Model.of(new ArrayList<String>()), new ListModel<String> (theSmiths), render, 5, true));
----
*Screenshot:*
-image::../img/multi-select-transfer-component-wicket.png[]
+image::./img/multi-select-transfer-component-wicket.png[]
-The last two parameters of the Palette's constructor (an integer value and a boolean value) are, respectively, the number of visible rows for the two lists and a flag to choose if we want to display the two optional buttons which move selected options up and down. The descriptions of the two lists (“Available” and “Selected”) can be customized providing two resources with keys palette.available and palette.selected.
+The last two parameters of the Palette's constructor (an integer value and a boolean value) are, respectively, the number of visible rows for the two lists and a flag to choose if we want to display the two optional buttons which move selected options up and down. The descriptions of the two lists (“Available” and “Selected”) can be customized providing two resources with keys palette.available and palette.selected.
The markup of this component uses a number of CSS classes which can be extended/overriden to customize the style of the component. We can find these classes and see which tags they decorate in the default markup file of the component:
@@ -87,25 +87,25 @@ The markup of this component uses a number of CSS classes which can be extended/
<tr>
<td class="header headerAvailable"><span wicket:id="availableHeader">[available header]</span></td>
<td> </td>
- <td class="header headerSelected"><span wicket:id="selectedHeader">[selected header]</span>
- </td>
+ <td class="header headerSelected"><span wicket:id="selectedHeader">[selected header]</span>
+ </td>
</tr>
<tr>
<td class="pane choices">
- <select wicket:id="choices" class="choicesSelect">[choices]</select>
+ <select wicket:id="choices" class="choicesSelect">[choices]</select>
</td>
<td class="buttons">
- <button type="button" wicket:id="addButton" class="button add"><div/>
+ <button type="button" wicket:id="addButton" class="button add"><div/>
</button><br/>
- <button type="button" wicket:id="removeButton" class="button remove"><div/>
+ <button type="button" wicket:id="removeButton" class="button remove"><div/>
</button><br/>
- <button type="button" wicket:id="moveUpButton" class="button up"><div/>
+ <button type="button" wicket:id="moveUpButton" class="button up"><div/>
</button><br/>
- <button type="button" wicket:id="moveDownButton" class="button down"><div/>
+ <button type="button" wicket:id="moveDownButton" class="button down"><div/>
</button><br/>
</td>
<td class="pane selection">
- <select class="selectionSelect" wicket:id="selection">[selection]</select>
+ <select class="selectionSelect" wicket:id="selection">[selection]</select>
</td>
</tr>
</table>
diff --git a/wicket-user-guide/src/main/asciidoc/forms2/forms2_2.adoc b/wicket-user-guide/src/main/asciidoc/forms2/forms2_2.adoc
index 352034f09f..b77fd06727 100644
--- a/wicket-user-guide/src/main/asciidoc/forms2/forms2_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/forms2/forms2_2.adoc
@@ -3,7 +3,7 @@
A basic example of a validation rule is to make a field required. In <<modelsforms.adoc#_login_form,paragraph 11.4.2>> we have already seen how this can be done calling setRequired(true) on a field. However, to set a validation rule on a FormComponent we must add the corresponding validator to it.
-A validator is an implementation of the _org.apache.wicket.validation.IValidator_ interface and the _FormComponent_ has a version of method add which takes as input a reference of this interface.
+A validator is an implementation of the _org.apache.wicket.validation.IValidator_ interface and the _FormComponent_ has a version of method add which takes as input a reference of this interface.
For example if we want to use a text field to insert an email address, we could use the built-in validator EmailAddressValidator to ensure that the inserted input will respect the email format http://en.wikipedia.org/wiki/Email_address[local-part@domain] :
@@ -25,10 +25,10 @@ _Field '<label>' is required._
The entire infrastructure of feedback messages is built on top of the Java internationalization (I18N) support and it uses http://docs.oracle.com/javase/tutorial/i18n/resbundle/index.html[resource bundles] to store messages.
-NOTE: The topics of internationalization will be covered in
+NOTE: The topics of internationalization will be covered in
<<_internationalization_with_wicket,chapter 15>>. For now we will give just few notions needed to understand the examples from this chapter.
-By default resource bundles are stored into properties files but we can easily configure other sources as described later in <<i18n.adoc#_localization_in_wicket,paragraph 15.2>>.
+By default resource bundles are stored into properties files but we can easily configure other sources as described later in <<i18n.adoc#_localization_in_wicket,paragraph 15.2>>.
Default feedback messages (like the one above for required fields) are stored in the file Application. properties placed inside Wicket the org.apache.wicket package. Opening this file we can find the key and the localized value of the message:
@@ -48,16 +48,16 @@ To display feedback messages we must use component _org.apache.wicket.markup.htm
[source,html]
----
-<ul class="feedbackPanel">
- <li class="feedbackPanelERROR">
- <span class="feedbackPanelERROR">Field 'Username' is required.</span>
- </li>
+<ul class="feedbackPanel">
+ <li class="feedbackPanelERROR">
+ <span class="feedbackPanelERROR">Field 'Username' is required.</span>
+ </li>
</ul>
----
CSS classes _feedbackPanel_ and _feedbackPanelERROR_ can be used in order to customize the style of the message list:
-image::../img/feedback-panel-style.png[]
+image::./img/feedback-panel-style.png[]
The component can be freely placed inside the page and we can set the maximum amount of displayed messages with the setMaxMessages() method.
@@ -103,7 +103,7 @@ _The value of '${label}' is not between ${minimum} and ${maximum}._
==== RangeValidator
-Validator class that can be extended or used as a factory class to get validators to check if a value is bigger than a given lower bound (method minimum(T min)), smaller than a upper bound (method maximum(T max)) or inside a range (method range(T min,T max)).
+Validator class that can be extended or used as a factory class to get validators to check if a value is bigger than a given lower bound (method minimum(T min)), smaller than a upper bound (method maximum(T max)) or inside a range (method range(T min,T max)).
The type of the value is a generic subtype of java.lang.Comparable and must implement Serializable interface.
@@ -133,7 +133,7 @@ _The value of '${label}' is not exactly ${exact} characters long._
==== CreditCardValidator
-Checks if input is a valid credit card number. This validator supports some of the most popular credit cards (like “American Express”, “MasterCard” , “Visa” or “Diners Club”).
+Checks if input is a valid credit card number. This validator supports some of the most popular credit cards (like “American Express”, “MasterCard” , “Visa” or “Diners Club”).
*Message:*
@@ -141,7 +141,7 @@ _The credit card number is invalid._
==== EqualPasswordInputValidator
-This validator checks if two password fields have the same value.
+This validator checks if two password fields have the same value.
*Message:*
@@ -155,19 +155,19 @@ _EmailAddressValidator=Man, your email address is not good!_
As we will see in the next chapter, Wicket searches for custom properties files in various positions inside the application's class path, but for now we will consider just the properties file placed next to our application class. The name of this file must be equal to the name of our application class:
-image::../img/custom-properties-file.png[]
+image::./img/custom-properties-file.png[]
The example project OverrideMailMessage overrides email validator's message with a new one which also reports the value that failed validation:
_EmailAddressValidator=The value '${input}' inserted for field '${label}' is not a valid email address._
-image::../img/validation-error-message.png[]
+image::./img/validation-error-message.png[]
=== Creating custom validators
If our web application requires a complex validation logic and built-in validators are not enough, we can implement our own custom validators. For example (project UsernameCustomValidator) suppose we are working on the registration page of our site where users can create their profile choosing their username. Our registration form should validate the new username checking if it was already chosen by another user. In a situation like this we may need to implement a custom validator that [...]
-For the sake of simplicity, the validator of our example will check the given username against a fixed list of three existing usernames.
+For the sake of simplicity, the validator of our example will check the given username against a fixed list of three existing usernames.
A custom validator must simply implement interface IValidator:
@@ -178,20 +178,20 @@ public class UsernameValidator implements IValidator<String> {
public void validate(IValidatable<String> validatable) {
String chosenUserName = validatable.getValue();
-
+
if(existingUsernames.contains(chosenUserName)){
ValidationError error = new ValidationError(this);
Random random = new Random();
-
- error.setVariable("suggestedUserName",
+
+ error.setVariable("suggestedUserName",
validatable.getValue() + random.nextInt());
validatable.error(error);
}
- }
+ }
}
----
-The only method defined inside IValidator is validate(IValidatable<T> validatable) and is invoked during validation's step. Interface IValidatable represents the component being validated and it can be used to retrieve the component model (getModel()) or the value to validate (getValue()).
+The only method defined inside IValidator is validate(IValidatable<T> validatable) and is invoked during validation's step. Interface IValidatable represents the component being validated and it can be used to retrieve the component model (getModel()) or the value to validate (getValue()).
The custom validation logic is all inside IValidator's method validate. When validation fails a validator must use IValidatable's method error(IValidationError error) to generate the appropriate feedback message. In the code above we used the ValidationError class as convenience implementation of the IValidationError interface which represents the validation error that must be displayed to the user. This class provides a constructor that uses the class name of the validator in input as k [...]
@@ -207,14 +207,14 @@ The code of the home page of the project will be examined in the next paragraph
So far we have considered just the error messages generated during validation step. However Wicket's Component class provides a set of methods to explicitly generate feedback messages called flash messages. These methods are:
-* debug(Serializable message)
-* info(Serializable message)
-* success(Serializable message)
-* warn(Serializable message)
-* error(Serializable message)
-* fatal(Serializable message)
+* debug(Serializable message)
+* info(Serializable message)
+* success(Serializable message)
+* warn(Serializable message)
+* error(Serializable message)
+* fatal(Serializable message)
-Each of these methods corresponds to a level of severity for the message. The list above is sorted by increasing level of severity.
+Each of these methods corresponds to a level of severity for the message. The list above is sorted by increasing level of severity.
In the example seen in the previous paragraph we have a form which uses success method to notify user when the inserted username is valid. Inside this form there are two FeedbackPanel components: one to display the error message produced by custom validator and the other one to display the success message. The code of the example page is the following:
@@ -241,7 +241,7 @@ In the example seen in the previous paragraph we have a form which uses success
----
public class HomePage extends WebPage {
- public HomePage(final PageParameters parameters) {
+ public HomePage(final PageParameters parameters) {
Form<Void> form = new Form<Void>("form"){
@Override
protected void onSubmit() {
@@ -249,31 +249,31 @@ public class HomePage extends WebPage {
success("Username is good!");
}
};
-
+
TextField mail;
-
+
form.add(mail = new TextField("username", Model.of("")));
mail.add(new UsernameValidator());
-
- add(new FeedbackPanel("feedbackMessage",
+
+ add(new FeedbackPanel("feedbackMessage",
new ExactErrorLevelFilter(FeedbackMessage.ERROR)));
- add(new FeedbackPanel("succesMessage",
+ add(new FeedbackPanel("succesMessage",
new ExactErrorLevelFilter(FeedbackMessage.SUCCESS)));
-
+
add(form);
}
-
+
class ExactErrorLevelFilter implements IFeedbackMessageFilter{
private int errorLevel;
public ExactErrorLevelFilter(int errorLevel){
this.errorLevel = errorLevel;
}
-
+
public boolean accept(FeedbackMessage message) {
return message.getLevel() == errorLevel;
}
-
+
}
//UsernameValidator definition
//...
@@ -283,5 +283,5 @@ public class HomePage extends WebPage {
The two feedback panels must be filtered in order to display just the messages with a given level of severity (ERROR for validator message and SUCCESS for form's flash message). Unfortunately the built-in message filter ErrorLevelFeedbackMessageFilter is not suitable for this task because its filter condition does not check for an exact error level (the given level is used as lower bound value). As a consequence, we had to build a custom filter (inner class ExactErrorLevelFilter) to acce [...]
NOTE: Since version 6.13.0 Wicket provides the additional filter class org.apache.wicket.feedback.ExactLevelFeedbackMessageFilter to accept only feedback messages of a certain error level.
-
+
diff --git a/wicket-user-guide/src/main/asciidoc/forms2/forms2_3.adoc b/wicket-user-guide/src/main/asciidoc/forms2/forms2_3.adoc
index 2dd3cf5bf7..4c237f90e7 100644
--- a/wicket-user-guide/src/main/asciidoc/forms2/forms2_3.adoc
+++ b/wicket-user-guide/src/main/asciidoc/forms2/forms2_3.adoc
@@ -13,7 +13,7 @@ TextField integerField = new TextField("number", new Model()).setType(Integer.cl
If no type has been provided, FormComponent will try to ask its model for this information. The PropertyModel and CompoundPropertyModel models can use reflection to get the type of object model. By default, if FormComponent can not obtain the type of its model object in any way, it will consider it as a simple String.
-Once FormComponent has determined the type of model object, it can look up for a converter, which is the entity in charge of converting input to Java object and vice versa. Converters are instances of _org.apache.wicket.util.convert.IConverter_ interface and are registered by our application class on start up.
+Once FormComponent has determined the type of model object, it can look up for a converter, which is the entity in charge of converting input to Java object and vice versa. Converters are instances of _org.apache.wicket.util.convert.IConverter_ interface and are registered by our application class on start up.
To get a converter for a specific type we must call method getConverter(Class<C> type) on the interface IConverterLocator returned by Application's method getConverterLocator():
@@ -23,7 +23,7 @@ To get a converter for a specific type we must call method getConverter(Class<C>
Application.get().getConverterLocator().getConverter(Boolean.class);
----
-NOTE: Components which are subclasses of AbstractSingleSelectChoice don't follow the schema illustrated above to convert user input.
+NOTE: Components which are subclasses of AbstractSingleSelectChoice don't follow the schema illustrated above to convert user input.
These kinds of components (like DropDownChoice and RadioChoice) use their choice render and their collection of possible choices to perform input conversion.
@@ -62,11 +62,11 @@ public ConverterLocator()
If we want to add more converters to our application, we can override Application's method newConverterLocator which is used by application class to build its converter locator.
-To illustrate how to implement custom converters and use them in our application, we will build a form with two text field: one to input a regular expression pattern and another one to input a string value that will be split with the given pattern.
+To illustrate how to implement custom converters and use them in our application, we will build a form with two text field: one to input a regular expression pattern and another one to input a string value that will be split with the given pattern.
The first text field will have an instance of class java.util.regex.Pattern as model object. The final page will look like this (the code of this example is from the CustomConverter project):
-image::../img/regex-form.png[]
+image::./img/regex-form.png[]
The conversion between Pattern and String is quite straightforward. The code of our custom converter is the following:
@@ -85,7 +85,7 @@ public class RegExpPatternConverter implements IConverter<Pattern> {
}
----
-Methods declared by interface IConverter take as input a Locale parameter in order to deal with locale-sensitive data and conversions. We will learn more about locales and internationalization in
+Methods declared by interface IConverter take as input a Locale parameter in order to deal with locale-sensitive data and conversions. We will learn more about locales and internationalization in
<<_internationalization_with_wicket,Chapter 15>>.
Once we have implemented our custom converter, we must override method newConverterLocator() inside our application class and tell it to add our new converter to the default set:
@@ -95,44 +95,44 @@ Once we have implemented our custom converter, we must override method newConver
@Override
protected IConverterLocator newConverterLocator() {
ConverterLocator defaultLocator = new ConverterLocator();
-
+
defaultLocator.set(Pattern.class, new RegExpPatternConverter());
-
+
return defaultLocator;
}
----
-Finally, in the home page of the project we build the form which displays (with a flash message) the tokens obtained splitting the string with the given pattern:
+Finally, in the home page of the project we build the form which displays (with a flash message) the tokens obtained splitting the string with the given pattern:
[source,java]
----
public class HomePage extends WebPage {
private Pattern regExpPattern;
private String stringToSplit;
-
- public HomePage(final PageParameters parameters) {
+
+ public HomePage(final PageParameters parameters) {
TextField regExpPatternTxt;
TextField stringToSplitTxt;
-
+
Form<Void> form = new Form<Void>("form"){
@Override
protected void onSubmit() {
super.onSubmit();
String messageResult = "Tokens for the given string and pattern:<br/>";
String[] tokens = regExpPattern.split(stringToSplit);
-
+
for (String token : tokens) {
messageResult += "- " + token + "<br/>";
- }
+ }
success(messageResult);
}
};
-
+
form.setDefaultModel(new CompoundPropertyModel(this));
form.add(regExpPatternTxt = new TextField("regExpPattern"));
form.add(stringToSplitTxt = new TextField("stringToSplit"));
add(new FeedbackPanel("feedbackMessage").setEscapeModelStrings(false));
-
+
add(form);
}
}
diff --git a/wicket-user-guide/src/main/asciidoc/forms2/forms2_4.adoc b/wicket-user-guide/src/main/asciidoc/forms2/forms2_4.adoc
index 70a4829789..572b61718f 100644
--- a/wicket-user-guide/src/main/asciidoc/forms2/forms2_4.adoc
+++ b/wicket-user-guide/src/main/asciidoc/forms2/forms2_4.adoc
@@ -84,4 +84,4 @@ public HomePage(final PageParameters parameters) {
Now we can run our application an see that JSR 303 annotations are fully effective:
-image::../img/jsr303-form-validation.png[]
+image::./img/jsr303-form-validation.png[]
diff --git a/wicket-user-guide/src/main/asciidoc/forms2/forms2_5.adoc b/wicket-user-guide/src/main/asciidoc/forms2/forms2_5.adoc
index 9c220526a8..6d1f81056c 100644
--- a/wicket-user-guide/src/main/asciidoc/forms2/forms2_5.adoc
+++ b/wicket-user-guide/src/main/asciidoc/forms2/forms2_5.adoc
@@ -1,13 +1,13 @@
-Besides submitting forms with a standard HTML submit button, Wicket allows us to use special components which implement interface IFormSubmittingComponent. This entity is a subinterface of IFormSubmitter:
+Besides submitting forms with a standard HTML submit button, Wicket allows us to use special components which implement interface IFormSubmittingComponent. This entity is a subinterface of IFormSubmitter:
-image::../img/class-diag-IFormSubmittingComponent.png[]
+image::./img/class-diag-IFormSubmittingComponent.png[]
At the beginning of this chapter we have seen that form processing is started by process method which takes as input an instance of IFormSubmitter. This parameter corresponds to the IFormSubmittingComponent clicked by a user to submit the form and it is null if we have used a standard HTML submit button (like we have done so far).
-A submitting component is added to a form just like any other child component using method add(Component...).
+A submitting component is added to a form just like any other child component using method add(Component...).
A form can have any number of submitting components and we can specify which one among them is the default one by calling the Form's method setDefaultButton(IFormSubmittingComponent component). The default submitter is the one that will be used when user presses 'Enter' key in a field of the form. In order to make the default button work, Wicket will add to our form a hidden <div> tag containing a text field and a submit button with some JavaScript code to trigger it:
@@ -48,15 +48,15 @@ In the following snippet we have a form with two submit buttons bound to an <inp
[source,java]
----
public class HomePage extends WebPage {
-
- public HomePage(final PageParameters parameters) {
+
+ public HomePage(final PageParameters parameters) {
Form<Void> form = new Form<>("form");
-
+
form.add(new TextField("username", Model.of("")));
form.add(new Button("submit1", Model.of("First submitter")));
Button secondSubmitter;
form.add(secondSubmitter = new Button("submit2", Model.of("Second submitter")));
-
+
form.setDefaultButton(secondSubmitter);
add(form);
}
@@ -72,7 +72,7 @@ public class HomePage extends WebPage {
...
<!-- Code generated by Wicket to handle the default button -->
...
- </div>
+ </div>
Username: <input type="text" wicket:id="username" value="" name="username"/>
<br/>
<input type="submit" wicket:id="submit1" name="submit1" id="submit13" value="First submitter"/>
@@ -94,7 +94,7 @@ A notable difference between this component and Button is that SubmitLink can be
<body>
<form wicket:id="form">
Password: <input type="password" wicket:id="password"/>
- <br/>
+ <br/>
</form>
<button wicket:id="externalSubmitter">
Submit
@@ -108,10 +108,10 @@ A notable difference between this component and Button is that SubmitLink can be
[source,java]
----
public class HomePage extends WebPage {
-
- public HomePage(final PageParameters parameters) {
+
+ public HomePage(final PageParameters parameters) {
Form<Void> form = new Form<>("form");
-
+
form.add(new PasswordTextField("password", Model.of("")));
//specify the form to submit
add(new SubmitLink("externalSubmitter", form));
@@ -124,7 +124,7 @@ public class HomePage extends WebPage {
With an IFormSubmittingComponent we can choose to skip the default form submission process by setting the appropriate flag to false with the setDefaultFormProcessing method. When the default form processing is disabled only the submitter's onSubmit is called while form's validation and models updating are skipped.
-This can be useful if we want to implement a “Cancel” button on our form which redirects user to another page without validating his/her input.
+This can be useful if we want to implement a “Cancel” button on our form which redirects user to another page without validating his/her input.
When we set this flag to false we can decide to manually invoke the form processing by calling the process(IFormSubmittingComponent) method.
diff --git a/wicket-user-guide/src/main/asciidoc/helloWorld.adoc b/wicket-user-guide/src/main/asciidoc/helloWorld.adoc
index 3408fb315d..b285f689ef 100644
--- a/wicket-user-guide/src/main/asciidoc/helloWorld.adoc
+++ b/wicket-user-guide/src/main/asciidoc/helloWorld.adoc
@@ -1,8 +1,8 @@
-Wicket allows us to design our web pages in terms of components and containers, just like AWT does with desktop windows.
+Wicket allows us to design our web pages in terms of components and containers, just like AWT does with desktop windows.
Both frameworks share the same component-based architecture: in AWT we have a _Windows_ instance which represents the physical windows containing GUI components (like text fields, radio buttons, drawing areas, etc...), in Wicket we have a _WebPage_ instance which represents the physical web page containing HTML components (pictures, buttons, forms, etc... ) .
-image::../img/uml-component.png[]
+image::./img/uml-component.png[]
In both frameworks we find a base class for GUI components called _Component_. Wicket pages can be composed (and usually are) by many components, just like AWT windows are composed by Swing/AWT components. Both frameworks promote the reuse of presentation code and GUI elements building custom components. Even if Wicket already comes with a rich set of ready-to-use components, building custom components is a common practice when working with this framework. We'll learn more about custom c [...]
diff --git a/wicket-user-guide/src/main/asciidoc/helloWorld/helloWorld_2.adoc b/wicket-user-guide/src/main/asciidoc/helloWorld/helloWorld_2.adoc
index 0824faadc7..a2851bb03c 100644
--- a/wicket-user-guide/src/main/asciidoc/helloWorld/helloWorld_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/helloWorld/helloWorld_2.adoc
@@ -7,7 +7,7 @@ NOTE: All the example projects presented in this document have been generated us
A Wicket application is a standard Java EE web application, hence it is deployed through a _web.xml_ file placed inside folder WEB-INF:
-image::../img/webinf.png[]
+image::./img/webinf.png[]
_Illustration: The standard directory structure of a Wicket application_
diff --git a/wicket-user-guide/src/main/asciidoc/helloWorld/helloWorld_3.adoc b/wicket-user-guide/src/main/asciidoc/helloWorld/helloWorld_3.adoc
index 19f353d264..7cd16c675d 100644
--- a/wicket-user-guide/src/main/asciidoc/helloWorld/helloWorld_3.adoc
+++ b/wicket-user-guide/src/main/asciidoc/helloWorld/helloWorld_3.adoc
@@ -1,12 +1,12 @@
-To complete our first Wicket application we must explore the home page class that is returned by the _Application_'s method _getHomePage()_ seen above.
+To complete our first Wicket application we must explore the home page class that is returned by the _Application_'s method _getHomePage()_ seen above.
In Wicket a web page is a subclass of _org.apache.wicket.WebPage_. This subclass must have a corresponding HTML file which will be used by the framework as template to generate its HTML markup. This file is a regular plain HTML file (its extension must be html).
By default this HTML file must have the same name of the related page class and must be in the same package:
-image::../img/samepackage.png[]
+image::./img/samepackage.png[]
_Illustration: Page class and its related HTML file_
@@ -22,14 +22,14 @@ import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.WebPage;
-public class HomePage extends WebPage {
+public class HomePage extends WebPage {
public HomePage() {
add(new Label("helloMessage", "Hello WicketWorld!"));
}
}
----
-Apart from subclassing _WebPage_, _HomePage_ defines a constructor that adds a _Label_ component to itself.
+Apart from subclassing _WebPage_, _HomePage_ defines a constructor that adds a _Label_ component to itself.
Method _add(Component component)_ is inherited from ancestor class _org.apache.wicket.MarkupContainer_ and is used to add children components to a web page. We'll see more about _MarkupContainer_ later in <<_here_comes_the_inheritance,chapter 5.2>>.
Class _org.apache.wicket.markup.html.basic.Label_ is the simplest component shipped with Wicket. It just inserts a string (the second argument of its constructor) inside the corresponding HTML tag.
Just like any other Wicket component, _Label_ needs a textual id (_'helloMessage'_ in our example) to be instantiated. At runtime Wicket will use this value to find the HTML tag we want to bind to the component. This tag must have a special attribute called _wicket:id_ and its value must be identical to the component id (comparison is case-sensitive!).
@@ -45,7 +45,7 @@ Here is the HTML markup for _HomePage_ (file HomePage.html):
<title>Apache Wicket HelloWorld</title>
</head>
<body>
-
+
<div wicket:id="helloMessage">
[Label's message goes here]
</div>
diff --git a/wicket-user-guide/src/main/asciidoc/howToSource.adoc b/wicket-user-guide/src/main/asciidoc/howToSource.adoc
index c92640facf..3941fd98c8 100644
--- a/wicket-user-guide/src/main/asciidoc/howToSource.adoc
+++ b/wicket-user-guide/src/main/asciidoc/howToSource.adoc
@@ -8,10 +8,10 @@ git clone https://github.com/bitstorm/Wicket-tutorial-examples.git
If you aren't used to Git, you can simply download the whole source as a zip archive:
-image::../img/gitRepo.png[]
+image::./img/gitRepo.png[]
The repository contains a multi-module Maven project. Every subproject is contained in the relative folder of the repository:
-image::../img/gitMavenPrj.png[]
+image::./img/gitMavenPrj.png[]
When the example code is used in the document, you will find the name of the subproject it belongs to. If you don't have any experience with Maven, you can read Appendix A where you can learn the basic commands needed to work with the example projects and to import them into your favourite IDE (NetBeans, IDEA or Eclipse).
diff --git a/wicket-user-guide/src/main/asciidoc/i18n/i18n_2.adoc b/wicket-user-guide/src/main/asciidoc/i18n/i18n_2.adoc
index 6721042424..b763b79631 100644
--- a/wicket-user-guide/src/main/asciidoc/i18n/i18n_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/i18n/i18n_2.adoc
@@ -3,7 +3,7 @@
A component can get the current locale in use calling its method getLocale(). By default this method will be recursively called on component's parent containers until one of them returns a valid locale. If no one of them returns a locale, this method will get the one associated with the current user session. This locale is automatically generated by Wicket in accordance with the language settings of the browser.
-Developers can change the locale of the current session with Session's method setLocale (Locale locale):
+Developers can change the locale of the current session with Session's method setLocale (Locale locale):
[source,java]
----
@@ -29,7 +29,7 @@ If set, style's value contributes to the final full name of the bundle and it is
Wicket gives the priority to candidate names containing the style information (if available). The other parameter we can use for localization is variation. Just like style also variation is a string value, but it is defined at component-level. The value of variation is returned by Component's method getVariation(). By default this method returns the variation of the parent component or a null value if a component hasn't a parent (i.e. it's a page). If we want to customize this parameter [...]
-Variation's value contributes to the final full name of the bundle and is placed before style parameter:
+Variation's value contributes to the final full name of the bundle and is placed before style parameter:
[source,java]
----
@@ -82,7 +82,7 @@ greetingMessage=Welcome to the site!
Along with this file we can also find a bundle for German (WicketApplication_de.properties) and another one in XML format for simplified Chinese (WicketApplication_zh.properties.xml). The example project consists of a single page (HomePage.java) displaying the greeting message. The current locale can be changed with a drop-down list and the possible options are English (the default one), German and simplified Chinese:
-image::../img/locale-german.png[]
+image::./img/locale-german.png[]
The label displaying the greeting message has a custom read-only model which returns the message with method getString. The initialization code for this label is this:
@@ -98,16 +98,16 @@ The rest of the code of the home page builds the stateless form and the drop-dow
[source,java]
----
List<Locale> locales = Arrays.asList(Locale.ENGLISH, Locale.CHINESE, Locale.GERMAN);
-final DropDownChoice<Locale> changeLocale =
+final DropDownChoice<Locale> changeLocale =
new DropDownChoice<Locale>("changeLocale", new Model<Locale>(), locales);
-
+
StatelessForm<Void> form = new StatelessForm<Void>("form"){
@Override
protected void onSubmit() {
Session.get().setLocale(changeLocale.getModelObject());
}
-};
-
+};
+
setStatelessHint(true);
add(form.add(changeLocale))
----
@@ -117,7 +117,7 @@ add(form.add(changeLocale))
Although resource bundles exist to extract local-dependent elements from our code and from UI components, in Wicket we can decide to provide different markup files for different locale settings. Just like standard markup files, by default localized markup files must be placed next to component's class and their file name must contain the locale's informations. In the following picture, CustomPanel comes with a standard (or default) markup file and with another one localized for German:
-image::../img/comp-with-markup-german.png[]
+image::./img/comp-with-markup-german.png[]
When the current locale corresponds to German country (language code de), markup file CustomPanel_de.html will be used in place of the default one.
@@ -175,7 +175,7 @@ and
----
add(new Label("amount",new Model("$5.00")));
-add(new BookmarkablePageLink("link",DetailsPage.class));
+add(new BookmarkablePageLink("link",DetailsPage.class));
----
Results in:
diff --git a/wicket-user-guide/src/main/asciidoc/i18n/i18n_3.adoc b/wicket-user-guide/src/main/asciidoc/i18n/i18n_3.adoc
index 7558a3a9ff..c0d574250b 100644
--- a/wicket-user-guide/src/main/asciidoc/i18n/i18n_3.adoc
+++ b/wicket-user-guide/src/main/asciidoc/i18n/i18n_3.adoc
@@ -7,19 +7,19 @@ As we hinted at the beginning of this chapter, by default Wicket provides a very
Similarly to application class, also component classes can have their own bundle files having as base name the class name of the related component and placed in the same package. So for example if class CustomPanel is a custom panel we created, we can provide it with a default bundle file called CustomPanel.properties containing the textual resources used by this panel. This rule applies to page classes as well:
-image::../img/page-and-panel-bundle.png[]
+image::./img/page-and-panel-bundle.png[]
One fundamental thing to keep in mind when we work with these kinds of bundles is that the lookup algorithm gives priority to the bundles of the containers of the component that is requesting a localized resource. The more a container is higher in the hierarchy, the bigger is its priority over the other components. This mechanism was made to allow containers to overwrite resources used by children components. As a consequence the values inside the resource bundle of a page will have the [...]
To better grasp this concept let's consider the component hierarchy depicted in the following picture:
-image::../img/custom-panel-bundle.png[]
+image::./img/custom-panel-bundle.png[]
If CustomPanel tries to retrieve the string resource having 'message' as key, it will get the value 'Wellcome!' and not the one defined inside its own bundle file.
The default message-lookup algorithm is not limited to component hierarchy but it also includes the class hierarchy of every component visited in the search strategy described so far. This makes bundle files inheritable, just like markup files. When the hierarchy of a container component is explored, any ancestor has the priority over children components. Consider for example the hierarchy in the following picture:
-image::../img/custom-panel-bundle2.png[]
+image::./img/custom-panel-bundle2.png[]
Similarly to the previous example, the bundle owned by CustomPanel is overwritten by the bundle of page class BasePage (which has been inherited by CustomPage).
@@ -69,7 +69,7 @@ With the code and the bundle above, the label inside the form will display the v
If no one of the previous steps can find a resource for the given key, the algorithm will look for package bundles. These bundles have _wicket-package_ as base name and they can be placed in one of the package of our application:
-image::../img/package-bundles.png[]
+image::./img/package-bundles.png[]
Packages are traversed starting from the one containing the component requesting for a resource and going up to the root package.
@@ -77,7 +77,7 @@ Packages are traversed starting from the one containing the component requesting
The algorithm described so far applies to feedback messages as well. In case of validation errors, the component that has caused the error will be considered as the component which the string resource is relative to. Furthermore, just like application class and components, validators can have their own bundles placed next to their class and having as base name their class name. This allows us to distribute validators along with the messages they use to report errors:
-image::../img/validator-with-bundle.png[]
+image::./img/validator-with-bundle.png[]
Validator's resource bundles have the lowest priority in the lookup algorithm. They can be overwritten by resource bundles of components, packages and application class.
@@ -101,7 +101,7 @@ public void init()
{
super.init();
//retrieve ResourceSettings and then the list of resource loaders
- List<IStringResourceLoader> resourceLoaders = getResourceSettings().
+ List<IStringResourceLoader> resourceLoaders = getResourceSettings().
getStringResourceLoaders();
//customize the list...
----
diff --git a/wicket-user-guide/src/main/asciidoc/internals/pagestoring.adoc b/wicket-user-guide/src/main/asciidoc/internals/pagestoring.adoc
index 31f0c05952..44092e6e98 100644
--- a/wicket-user-guide/src/main/asciidoc/internals/pagestoring.adoc
+++ b/wicket-user-guide/src/main/asciidoc/internals/pagestoring.adoc
@@ -4,12 +4,12 @@ When page class is provided _IPageSource_ delegates page creation to interface _
The following workflow diagram summarizes the mechanism seen so far:
-image::../img/page-storage.png[]
+image::./img/page-storage.png[]
=== IPageManager
_org.apache.wicket.page.IPageManager_'s task is to manage which pages have been used in a request and store their last state in the backing stores, namely _IPageStore_.
-The default implementation _org.apache.wicket.page.PageManager_ uses a chain of _IPageStore_ to collect all stateful pages which have been used in the request cycle and store them for a later use.
+The default implementation _org.apache.wicket.page.PageManager_ uses a chain of _IPageStore_ to collect all stateful pages which have been used in the request cycle and store them for a later use.
NOTE: Keep in mind that more than one page can be used in a single request if, for example, _setResponsePage()_ or _RestartResponseException_ are used.
@@ -21,8 +21,8 @@ NOTE: Wicket gets the default _IPageManager_ using a supplier interface called _
_org.apache.wicket.pageStore.IPageStore_'s role is to mediate the storing and loading of page instances. The default chain of _IPageStore_ used by Wicket contains the following ordered list of _IDataStore_:
-* *RequestPageStore:* collect all page instances involved in the last request. During the detach stage, stateful pages are passed to the othr steps of the chain to be persisted on file.
-* *InSessionPageStore:* with _InSessionPageStore_ the default chain keeps the last rendered page instance into the HTTP session for fast access.
+* *RequestPageStore:* collect all page instances involved in the last request. During the detach stage, stateful pages are passed to the othr steps of the chain to be persisted on file.
+* *InSessionPageStore:* with _InSessionPageStore_ the default chain keeps the last rendered page instance into the HTTP session for fast access.
* *SerializingPageStore:* _SerializingPageStore_ turns page instances into a more serialization-friendly format represented by class _org.apache.wicket.pageStore.SerializedPage_. This is a struct of:
[source,java]
@@ -40,7 +40,7 @@ i.e. this is the serialized page instance (data) plus additional information nee
* *CryptingPageStore:* page instances might contain sensible informations, therefore it's important to have the chance to encrypt their content before persist them on disk. _CryptingPageStore_ encrypts _SerializedPage_'s with a 256 bit AES before passing them to the underling _DiskPageStore_. Buy default this stage is disabled and not added to the default chain. To change this behavior we can use _org.apache.wicket.settings.StoreSettings.setEncrypted_.
-* *DiskPageStore:* stores _SerializedPage_ on a session-scoped file on disk. The location of the folder where the files are stored is configurable via _org.apache.wicket.settings.StoreSettings.setFileStoreFolder(File)_, by default the web container's work folder is used (ServletContext attribute 'javax.servlet.context.tempdir'). In this folder a sub-folder is created named _'applicationName-filestore'_.
+* *DiskPageStore:* stores _SerializedPage_ on a session-scoped file on disk. The location of the folder where the files are stored is configurable via _org.apache.wicket.settings.StoreSettings.setFileStoreFolder(File)_, by default the web container's work folder is used (ServletContext attribute 'javax.servlet.context.tempdir'). In this folder a sub-folder is created named _'applicationName-filestore'_.
This folder contains a sub-folder for each active http session. This session folder contains a single file named 'data' which contains the bytes for the pages. The size of this 'data' file is configurable via _org.apache.wicket.settings.StoreSettings.setMaxSizePerSession(Bytes)_. When this size is exceeded the newly stored files overwrite the oldest ones.
=== InMemoryPageStore
@@ -51,7 +51,7 @@ An alternative _IPageStore_ we can use in a custom chain is _org.apache.wicket.p
Further insights which can be valuable during debugging can be retrieved using the _org.apache.wicket.devutils.debugbar.DebugBar_ from wicket-devutils.jar. It's a panel which you simply add:
-Java:
+Java:
[source,java]
----
add(new DebugBar("debug"));
diff --git a/wicket-user-guide/src/main/asciidoc/introduction.adoc b/wicket-user-guide/src/main/asciidoc/introduction.adoc
index 33e3ee6727..f13f1f8458 100644
--- a/wicket-user-guide/src/main/asciidoc/introduction.adoc
+++ b/wicket-user-guide/src/main/asciidoc/introduction.adoc
@@ -7,7 +7,7 @@ However Wicket never provided a freely available documentation and even if you c
That's quite an issue because many other popular frameworks (like Spring, Hibernate or Struts) offer a vast and very good documentation which substantially contributed to their success.
This document is not intended to be a complete reference for Wicket but it simply aims to be a straightforward introduction to the framework that should significantly reduce its learning curve. What you will find here reflects my experience with Wicket and it's strictly focused on the framework.
-The various Wicket-related topics are gradually introduced using pragmatic examples of code that you can find in https://github.com/bitstorm/Wicket-tutorial-examples[the according repository on Github.]
+The various Wicket-related topics are gradually introduced using pragmatic examples of code that you can find in https://github.com/bitstorm/Wicket-tutorial-examples[the according repository on Github.]
However remember that Wicket is a vast and powerful tool, so you should feel confident with the topics exposed in this document before starting to code your real applications!
For those who need further documentation on Wicket, there are http://wicket.apache.org/learn/books/[many good books] available for this framework.
@@ -30,7 +30,7 @@ Editors: +
*PS*: this guide is based on Wicket 9. However if you are using an older version you should find this guide useful as well, but it's likely that the code and the snippets won't work with your version. +
*PPS*: although we try to do our best working on this guide, this document is a work in progress and may contain errors and/or omissions. That's why any feedback of any kind is REALLY appreciated!
-Project started by
+Project started by
-image::../img/comsysto-logo.png[link="http://comsysto.com/"]
+image::./img/comsysto-logo.png[link="http://comsysto.com/"]
diff --git a/wicket-user-guide/src/main/asciidoc/jee/jee_1.adoc b/wicket-user-guide/src/main/asciidoc/jee/jee_1.adoc
index 09ef16a4c7..eef27fae76 100644
--- a/wicket-user-guide/src/main/asciidoc/jee/jee_1.adoc
+++ b/wicket-user-guide/src/main/asciidoc/jee/jee_1.adoc
@@ -3,22 +3,22 @@
WicketStuff provides a module called wicketstuff-javaee-inject that contains component instantiation listener _JavaEEComponentInjector_. If we register this listener in our application we can use standard EJB annotations to inject dependencies into our Wicket components.
-To register a component instantiation listener in Wicket we must use _Application_'s method _getComponentInstantiationListeners_ which returns a typed collection of _IComponentInstantiationListeners_.
+To register a component instantiation listener in Wicket we must use _Application_'s method _getComponentInstantiationListeners_ which returns a typed collection of _IComponentInstantiationListeners_.
-The following initialization code is taken from project _EjbInjectionExample_:
+The following initialization code is taken from project _EjbInjectionExample_:
[source,java]
----
public class WicketApplication extends WebApplication
-{
+{
//Constructor...
@Override
public void init()
{
super.init();
- getComponentInstantiationListeners().add(new JavaEEComponentInjector(this));
- }
+ getComponentInstantiationListeners().add(new JavaEEComponentInjector(this));
+ }
}
----
@@ -37,14 +37,14 @@ Please note that we have used annotation ManagedBean to decorate our object. Now
[source,java]
----
public class HomePage extends WebPage {
-
+
@EJB
private EnterpriseMessage enterpriseMessage;
//getter and setter for enterpriseMessage...
-
+
public HomePage(final PageParameters parameters) {
super(parameters);
-
+
add(new Label("message", enterpriseMessage.message));
}
}
@@ -52,5 +52,5 @@ public class HomePage extends WebPage {
That is all. We can point the browser to the home page of the project and see the greeting message injected into the page:
-image::../img/EjbInjectionExample.png[]
+image::./img/EjbInjectionExample.png[]
diff --git a/wicket-user-guide/src/main/asciidoc/jsintegration/jsintegration_1.adoc b/wicket-user-guide/src/main/asciidoc/jsintegration/jsintegration_1.adoc
index cc92cc38fe..867237e464 100644
--- a/wicket-user-guide/src/main/asciidoc/jsintegration/jsintegration_1.adoc
+++ b/wicket-user-guide/src/main/asciidoc/jsintegration/jsintegration_1.adoc
@@ -1,13 +1,13 @@
-For end-users a datepicker is one of the most appreciated widget. It allows to simply edit a date value with the help of a user-friendly pop-up calendar. That's why nearly all UI frameworks provide a version of this widget.
+For end-users a datepicker is one of the most appreciated widget. It allows to simply edit a date value with the help of a user-friendly pop-up calendar. That's why nearly all UI frameworks provide a version of this widget.
-Popular JavaScript libraries like YUI and JQuery come with a ready-to-use datepicker to enrich the user experience of our web applications. Wicket already provides a component which integrates a text field with a calendar widget from YUI library, but there is no built-in component that uses a datepicker based on JQuery library.
+Popular JavaScript libraries like YUI and JQuery come with a ready-to-use datepicker to enrich the user experience of our web applications. Wicket already provides a component which integrates a text field with a calendar widget from YUI library, but there is no built-in component that uses a datepicker based on JQuery library.
As both JQuery and its child project JQueryUI have gained a huge popularity in the last years, it's quite interesting to see how to integrate them in Wicket building a custom component. In this chapter we will create a custom datepicker based on the corresponding widget from JQueryUI project:
-image::../img/datepicker-screenshot.png[]
+image::./img/datepicker-screenshot.png[]
WARNING: On Internet you can find different libraries that already offer a strong integration between Wicket and JQuery. The goal of this chapter is to see how to integrate Wicket with a JavaScript framework building a simple homemade datepicker which is not intended to provide every feature of the original JavaScript widget.
@@ -16,7 +16,7 @@ WARNING: On Internet you can find different libraries that already offer a stron
Before starting to write code, we must clearly define what features we want to implement for our component. The new component should:
* *Be self-contained*: we must be able to distribute it and use it in other projects without requiring any kind of additional configuration.
-* *Have a customizable date format*: developer must be able to decide the date format used to display date value and to parse user input.
+* *Have a customizable date format*: developer must be able to decide the date format used to display date value and to parse user input.
* *Be localizable*: the pop-up calendar must be localizable in order to support different languages.
That's what we'd like to have with our custom datepicker. In the rest of the chapter we will see how to implement the features listed above and which resources must be packaged with our component.
diff --git a/wicket-user-guide/src/main/asciidoc/jsintegration/jsintegration_2.adoc b/wicket-user-guide/src/main/asciidoc/jsintegration/jsintegration_2.adoc
index 205e7d34fa..2b0053d0cb 100644
--- a/wicket-user-guide/src/main/asciidoc/jsintegration/jsintegration_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/jsintegration/jsintegration_2.adoc
@@ -1,11 +1,11 @@
-Our new component will extend the built-in text field _org.apache.wicket.extensions.markup.html.form.DateTextField_ which already uses a java.util.Date as model object and already performs conversion and validation for input values. Since the component must be self-contained, we must ensure that the JavaScript libraries it relies on (JQuery and JQuery UI) will be always available.
+Our new component will extend the built-in text field _org.apache.wicket.extensions.markup.html.form.DateTextField_ which already uses a java.util.Date as model object and already performs conversion and validation for input values. Since the component must be self-contained, we must ensure that the JavaScript libraries it relies on (JQuery and JQuery UI) will be always available.
-Starting from version 6.0 Wicket has adopted JQuery as backing JavaScript library so we can use the version bundled with Wicket for our custom datepicker.
+Starting from version 6.0 Wicket has adopted JQuery as backing JavaScript library so we can use the version bundled with Wicket for our custom datepicker.
-To make JQuery UI available we should instead go to its official site, download the required artifacts and use them as package resources of our component.
+To make JQuery UI available we should instead go to its official site, download the required artifacts and use them as package resources of our component.
=== Component package resources
@@ -18,7 +18,7 @@ JQuery UI needs the following static resources in order to work properly:
In the following picture we can see these package resources with our component class (named JQueryDateField):
-image::../img/datepicker-package-resources.png[]
+image::./img/datepicker-package-resources.png[]
Along with the four static resources listed above, we can find also file calendar.jpg, which is the calendar icon used to open the pop up calendar, and file JQDatePicker.js which contains the following custom JavaScript code that binds our component to a JQuery UI datepicker:
@@ -29,7 +29,7 @@ function initJQDatepicker(inputId, countryIsoCode, dateFormat, calendarIcon) {
localizedArray['buttonImage'] = calendarIcon;
localizedArray['dateFormat'] = dateFormat;
initCalendar(localizedArray);
- $("#" + inputId).datepicker(localizedArray);
+ $("#" + inputId).datepicker(localizedArray);
};
function initCalendar(localizedArray){
@@ -60,42 +60,42 @@ The component is based on _LocalDateTextField_ which supports pattern-based conv
public class JQueryDateField extends LocalDateTextField {
/**
- *
+ *
*/
private static final long serialVersionUID = 5088998263851588184L;
private final String datePattern;
private final String countryIsoCode;
private CharSequence urlForIcon;
- private static final PackageResourceReference JQDatePickerRef =
+ private static final PackageResourceReference JQDatePickerRef =
new PackageResourceReference(JQueryDateField.class, "JQDatePicker.js");
-
- public JQueryDateField(String id, IModel<LocalDate> dateModel,
+
+ public JQueryDateField(String id, IModel<LocalDate> dateModel,
String datePattern, String countryIsoCode){
super(id, dateModel, datePattern);
this.datePattern = datePattern;
this.countryIsoCode = countryIsoCode;
}
-
+
@Override
protected void onInitialize() {
super.onInitialize();
-
+
setOutputMarkupId(true);
-
+
PackageResourceReference resourceReference = new PackageResourceReference(getClass(), "calendar.jpg");
-
+
urlForIcon = urlFor(resourceReference, new PageParameters());
-
+
add(AttributeModifier.replace("size", "12"));
}
-...
+...
----
-The first thing we do inside onInitialize is to ensure that our component will have a markup id for its related text field. This is done invoking setOutputMarkupId(true).
+The first thing we do inside onInitialize is to ensure that our component will have a markup id for its related text field. This is done invoking setOutputMarkupId(true).
Next, to generate the relative URL for the calendar icon we load its file as package resource reference and then we use _Component_'s method urlFor to get the URL value (we have seen this method in <<requestProcessing.adoc#_the_director_of_request_processing_requestcycle,paragraph 9.3.2>>).
-NOTE: as you might have noted in the constructor we need to pass the ISO language code along with the date pattern. The ISO code will be used to generate the JavaScript for the calendar.
+NOTE: as you might have noted in the constructor we need to pass the ISO language code along with the date pattern. The ISO code will be used to generate the JavaScript for the calendar.
=== Header contributor code
@@ -107,12 +107,12 @@ The rest of the code of our custom component is inside method _renderHeader_, wh
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
-
+
//if component is disabled we don't have to load the JQueryUI datepicker
if(!isEnabledInHierarchy())
return;
//add bundled JQuery
- JavaScriptLibrarySettings javaScriptSettings =
+ JavaScriptLibrarySettings javaScriptSettings =
getApplication().getJavaScriptLibrarySettings();
response.render(JavaScriptHeaderItem.
forReference(javaScriptSettings.getJQueryReference()));
@@ -125,7 +125,7 @@ public void renderHead(IHeaderResponse response) {
forReference(new PackageResourceReference(getClass(), "jquery-ui.css")));
//add custom file JQDatePicker.js. Reference JQDatePickerRef is a static field
response.render(JavaScriptHeaderItem.forReference(JQDatePickerRef));
-
+
//add the init script for datepicker
String jqueryDateFormat = datePattern.replace("yyyy", "yy").toLowerCase();
String initScript = ";initJQDatepicker('" + getMarkupId() + "', '" + countryIsoCode +
@@ -144,6 +144,6 @@ NOTE: If we add more than one instance of our custom component to a single page,
This does not apply to the init script which is dynamically generated and is rendered for every instance of the component.
-WARNING: Our datepicker is not ready yet to be used with AJAX. In
+WARNING: Our datepicker is not ready yet to be used with AJAX. In
<<_working_with_ajax,chapter 19>> we will see how to modify it to make it AJAX-compatible.
diff --git a/wicket-user-guide/src/main/asciidoc/layout/layout_1.adoc b/wicket-user-guide/src/main/asciidoc/layout/layout_1.adoc
index 4ab4e531f4..a4be493f68 100644
--- a/wicket-user-guide/src/main/asciidoc/layout/layout_1.adoc
+++ b/wicket-user-guide/src/main/asciidoc/layout/layout_1.adoc
@@ -5,22 +5,22 @@ With the adoption of server side technologies like JSP, ASP or PHP the tag _<fra
In this chapter we will see how to use Wicket to build a site layout. The sample layout we will use is a typical page layout consisting of the following areas:
-* *a header* which could contain site title, some logos, a navigation bar, etc...
-* *a left* menu with a bunch of links to different areas/functionalities of the site.
+* *a header* which could contain site title, some logos, a navigation bar, etc...
+* *a left* menu with a bunch of links to different areas/functionalities of the site.
* *a footer* with generic informations like web master's email, the company address, etc...
* *a content* area which usually contains the functional part of the page.
The following picture summarises the layout structure:
-image::../img/layout.png[]
+image::./img/layout.png[]
Once we have chosen a page layout, our web designer can start building up the site theme. The result is a beautiful mock of our future web pages. Over this mock we can map the original layout areas:
-image::../img/layout-mock.png[]
+image::./img/layout-mock.png[]
Now in order to have a consistent layout across all the site, we must ensure that each page will include the layout areas seen above. With an old template-based approach we must manually put them inside every page. If we were using JSP we would probably end up using _include_ directive to add layout areas in our pages. We would have one _include_ for each of the areas (except for the content):
-image::../img/layout-include.png[]
+image::./img/layout-include.png[]
NOTE: For the sake of simplicity we can consider each included area as a static HTML fragment.
diff --git a/wicket-user-guide/src/main/asciidoc/layout/layout_2.adoc b/wicket-user-guide/src/main/asciidoc/layout/layout_2.adoc
index 0e2872376a..3c631c6921 100644
--- a/wicket-user-guide/src/main/asciidoc/layout/layout_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/layout/layout_2.adoc
@@ -1,5 +1,5 @@
-The need of ensuring a consistent layout across our pages unveiled a serious limit of the HTML: the inability to apply inheritance to web pages and their markup. Wouldn't be great if we could write our layout once in a page and then inherit it in the other pages of our application?
+The need of ensuring a consistent layout across our pages unveiled a serious limit of the HTML: the inability to apply inheritance to web pages and their markup. Wouldn't be great if we could write our layout once in a page and then inherit it in the other pages of our application?
One of the goals of Wicket is to overcome this kind of limit.
=== Markup inheritance
@@ -8,7 +8,7 @@ As we have seen in the previous chapter, Wicket pages are pure Java classes, so
To better illustrate this concept let's consider the following example where we have a page class called _GenericSitePage_ with the corresponding HTML file GenericSitePage.html. Now let's create a specific page called _OrderCheckOutPage_ where users can check out their orders on our web site. This class extends _GenericSitePage_ but we don't provide it with any corresponding HTML file.
In this scenario _OrderCheckOutPage_ will use GenericSitePage.html as markup file:
-image::../img/markup-inheritance.png[]
+image::./img/markup-inheritance.png[]
Markup inheritance comes in handy for page layout management as it helps us avoid the burden of checking that each page conforms to the site layout. However to fully take advantage of markup inheritance we must first learn how to use another important component of the framework that supports this feature: the panel.
@@ -18,7 +18,7 @@ WARNING: If no markup is found (nor directly assigned to the class, neither inhe
Class _org.apache.wicket.markup.html.panel.Panel_ is a special component which lets us reuse GUI code and HTML markup across different pages and different web applications. It shares a common ancestor class with WebPage class, which is _org.apache.wicket.MarkupContainer_:
-image::../img/page-panel-hierarchy.png[]
+image::./img/page-panel-hierarchy.png[]
_Illustration: Hierarchy of WebPage and Panel classes_
diff --git a/wicket-user-guide/src/main/asciidoc/layout/layout_3.adoc b/wicket-user-guide/src/main/asciidoc/layout/layout_3.adoc
index c53a8b9f4b..a11284d15b 100644
--- a/wicket-user-guide/src/main/asciidoc/layout/layout_3.adoc
+++ b/wicket-user-guide/src/main/asciidoc/layout/layout_3.adoc
@@ -5,7 +5,7 @@ Let's go back to our layout example. In <<layout.adoc#_header_footer_left_menu_c
First, let's build a custom panel for each layout area (except for 'content' area). For example given the header area
-image::../img/header-area.png[]
+image::./img/header-area.png[]
we can build a panel called _HeaderPanel_ with a related markup file called HeaderPanel.html containing the HTML for this area:
@@ -26,10 +26,10 @@ we can build a panel called _HeaderPanel_ with a related markup file called Head
</td>
<td>
<h1>Gestione Anagrafica</h1>
- </td>
+ </td>
</tr>
</tbody>
- </table>
+ </table>
</wicket:panel>
</body>
<html>
@@ -46,14 +46,14 @@ import org.apache.wicket.markup.html.panel.Panel;
public class HeaderPanel extends Panel {
public HeaderPanel(String id) {
- super(id);
+ super(id);
}
}
----
For each layout area we will build a panel like the one above that holds the appropriate HTML markup. In the end we will have the following set of panels:
-* HeaderPanel
+* HeaderPanel
* FooterPanel
* MenuPanel
@@ -67,7 +67,7 @@ Now we can build a generic template page using our brand new panels. Its markup
----
<html>
<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
...
<!--Include CSS-->
...
@@ -100,16 +100,16 @@ public class JugTemplate extends WebPage {
private Component headerPanel;
private Component menuPanel;
private Component footerPanel;
-
+
public JugTemplate(){
add(headerPanel = new HeaderPanel("headerPanel"));
add(menuPanel = new MenuPanel("menuPanel"));
add(footerPanel = new FooterPanel("footerPanel"));
add(new Label(CONTENT_ID, "Put your content here"));
}
-
+
//getters for layout areas
- //...
+ //...
}
----
@@ -129,23 +129,23 @@ As final example we will build the login page for our site. We will call it _Sim
<div style="margin: auto; width: 40%;">
<form id="loginForm" method="get">
<fieldset id="login" class="center">
- <legend >Login</legend>
- <span >Username: </span><input type="text" id="username"/><br/>
+ <legend >Login</legend>
+ <span >Username: </span><input type="text" id="username"/><br/>
<span >Password: </span><input type="password" id="password" />
<p>
<input type="submit" name="login" value="login"/>
</p>
</fieldset>
</form>
- </div>
+ </div>
</wicket:panel>
</body>
</html>
----
-The class for this panel just extends _Panel_ class so we won't see the relative code. The form of this panel is for illustrative purpose only. We will see how to work with Wicket forms in chapters
-<<_wicket_models_and_forms,11>> and
-<<_wicket_forms_in_detail,12>>. Since this is a login page we don't want it to display the left menu area. That's not a big deal as _Component_ class exposes a method called _setVisible_ which sets whether the component and its children should be displayed.
+The class for this panel just extends _Panel_ class so we won't see the relative code. The form of this panel is for illustrative purpose only. We will see how to work with Wicket forms in chapters
+<<_wicket_models_and_forms,11>> and
+<<_wicket_forms_in_detail,12>>. Since this is a login page we don't want it to display the left menu area. That's not a big deal as _Component_ class exposes a method called _setVisible_ which sets whether the component and its children should be displayed.
The resulting Java code for the login page is the following:
@@ -158,7 +158,7 @@ import org.apache.wicket.event.IEventSink;
public class SimpleLoginPage extends JugTemplate {
public SimpleLoginPage(){
- super();
+ super();
replace(new LoginPanel(CONTENT_ID));
getMenuPanel().setVisible(false);
}
@@ -167,6 +167,6 @@ public class SimpleLoginPage extends JugTemplate {
Obviously this page doesn't come with a related markup file. You can see the final page in the following picture:
-image::../img/final-login-page.png[]
+image::./img/final-login-page.png[]
diff --git a/wicket-user-guide/src/main/asciidoc/maven/maven_2.adoc b/wicket-user-guide/src/main/asciidoc/maven/maven_2.adoc
index bb6d6b998b..432368d02e 100644
--- a/wicket-user-guide/src/main/asciidoc/maven/maven_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/maven/maven_2.adoc
@@ -2,7 +2,7 @@
NOTE: In order to follow the instructions of this paragraph you must have Maven installed on your system. The installation of Maven is out of the scope of this guide but you can easily find an extensive documentation about it on Internet.
-Another requirement is a good Internet connection (a flat ADSL is enough) because Maven needs to connect to its central repository to download the required dependencies.
+Another requirement is a good Internet connection (a flat ADSL is enough) because Maven needs to connect to its central repository to download the required dependencies.
=== From Maven to our IDE
@@ -10,7 +10,7 @@ Another requirement is a good Internet connection (a flat ADSL is enough) becaus
Wicket project and its dependencies are managed using Maven. This tool is very useful also when we want to create a new project based on Wicket from scratch. With a couple of shell commands we can generate a new project properly configured and ready to be imported into our favourite IDE.
The main step to create such a project is to run the command which generates project's structure and its artifacts. If we are not familiar with Maven or we simply don't want to type this command by hand, we can use the utility form on Wicket site at http://wicket.apache.org/start/quickstart.html[http://wicket.apache.org/start/quickstart.html] :
-image::../img/quickstart-webpage.png[]
+image::./img/quickstart-webpage.png[]
Here we have to specify the root package of our project (GroupId), the project name (ArtifactId) and which version of Wicket we want to use (Version).
Once we have run the resulting command in the OS shell, we will have a new folder with the same name of the project (i.e the ArtifactId). Inside this folder we can find a file called pom.xml. This is the main file used by Maven to manage our project. For example, using “org.wicketTutorial” as GroupId and “MyProject” as ArtifactId, we would obtain the following artifacts:
@@ -66,7 +66,7 @@ Amongst other things, file pom.xml contains a section delimited by tag <dependen
<artifactId>wicket-extensions</artifactId>
<version>${wicket.version}</version>
</dependency>
- -->
+ -->
...
</dependencies>
...
@@ -81,30 +81,30 @@ Maven projects can be easily imported into the most popular Java IDEs. However,
*NetBeans*
Starting from version 6.7, NetBeans includes Maven support, hence we can start it and directly open the folder containing our project:
-image::../img/netbeans-maven-import.png[]
+image::./img/netbeans-maven-import.png[]
*Intellj IDEA*
Intellj IDEA comes with a Maven importing functionality that can be started under “File/New Project/Import from external model/Maven”. Then, we just have to select the pom.xml file of our project:
-image::../img/intellj-maven-import.png[]
+image::./img/intellj-maven-import.png[]
*Eclipse*
Just like the other IDEs Eclipse supports Maven projects out of the box. Open the “File/Import...” dialog and search for Maven:
-image::../img/eclipse-maven-import.png[]
+image::./img/eclipse-maven-import.png[]
then, select the project folder containing the POM file:
-image::../img/eclipse-maven-select.png[]
+image::./img/eclipse-maven-select.png[]
-Once the project has been imported into Eclipse, we are free to use our favourite plug-ins to run it or debug it (like for example https://github.com/xzer/run-jetty-run/[run-jetty-run]).
+Once the project has been imported into Eclipse, we are free to use our favourite plug-ins to run it or debug it (like for example https://github.com/xzer/run-jetty-run/[run-jetty-run]).
=== Speeding up development with plugins.
Now that we have our project loaded into our IDE we could start coding our components directly by hand. However it would be a shame to not leverage the free and good Wicket plugins available for our IDE. The following is a brief overview of the most widely used plugins for each of the three main IDEs considered so far.
*NetBeans*
-NetBeans offers Wicket support through 'NetBeans Plugin for Wicket' hosted at http://plugins.netbeans.org/plugin/3586/wicket-1-4-support[http://plugins.netbeans.org/plugin/3586/wicket-1-4-support] . This plugin is released under CDDL-1.0 license.
+NetBeans offers Wicket support through 'NetBeans Plugin for Wicket' hosted at http://plugins.netbeans.org/plugin/3586/wicket-1-4-support[http://plugins.netbeans.org/plugin/3586/wicket-1-4-support] . This plugin is released under CDDL-1.0 license.
You can find a nice introduction guide to this plugin at http://netbeans.org/kb/docs/web/quickstart-webapps-wicket.html[http://netbeans.org/kb/docs/web/quickstart-webapps-wicket.html] .
*Intellj IDEA*
diff --git a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_1.adoc b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_1.adoc
index 8d99b09003..f7d0f13352 100644
--- a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_1.adoc
+++ b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_1.adoc
@@ -3,7 +3,7 @@
Model is essentially a http://en.wikipedia.org/wiki/Facade_pattern[facade] interface which allows components to access and modify their data without knowing any detail about how they are managed or persisted. Every component has at most one related model, while a model can be shared among different components. In Wicket a model is any implementation of the interface _org.apache.wicket.model.IModel_:
-image::../img/uml-imodel.png[]
+image::./img/uml-imodel.png[]
The main goal of _IModel_ interface is to decouple components from concrete details about the persistence strategy adopted for their data. In order to achieve this level of abstraction IModel defines the two methods required to get and set a data object: _getObject()_ and _setObject()_. The level of indirection introduced by models allows access data object only when it is really needed (for example during the rendering phase) and not earlier when it may not be ready to be used. In addi [...]
@@ -35,20 +35,20 @@ add(new Label("helloMessage", new Model<String>("Hello WicketWorld!")));
----
The Model class comes with a bunch of factory methods that makes it easier to build new model instances. For example the _of(T object)_ method creates a new instance of Model which wraps any Object instance inside it. So instead of writing
-
+
[source,java]
----
new Model<String>("Hello WicketWorld!")
----
we can write
-
+
[source,java]
----
Model.of("Hello WicketWorld!")
----
-If the data object is a _List_, a _Map_ or a _Set_ we can use similar methods called _ofList_, _ofMap_ and _ofSet_.
+If the data object is a _List_, a _Map_ or a _Set_ we can use similar methods called _ofList_, _ofMap_ and _ofSet_.
From now on we will use these factory methods in our examples.
It's quite clear that if our Label must display a static text it doesn't make much sense to build a model by hand like we did in the last code example.
diff --git a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_4.adoc b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_4.adoc
index a463f34820..7e16744ebc 100644
--- a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_4.adoc
+++ b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_4.adoc
@@ -33,7 +33,7 @@ In the next chapter we will continue to explore Wicket forms and we will see how
A form should contain some input fields (like text fields, check boxes, radio buttons, drop-down lists, text areas, etc.) to interact with users. Wicket provides an abstraction for all these kinds of elements with component org.apache.wicket.markup.html.form.FormComponent:
-image::../img/uml-form-component.png[]
+image::./img/uml-form-component.png[]
The purpose of FormComponent is to store the corresponding user input into its model when the form is submitted. The form is responsible for mapping input values to the corresponding components, avoiding us the burden of manually synchronizing models with input fields and vice versa.
diff --git a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_5.adoc b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_5.adoc
index 92e7316418..6b3db73a61 100644
--- a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_5.adoc
+++ b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_5.adoc
@@ -23,7 +23,7 @@ form.add(new DropDownChoice<String>("fruits", new Model(), fruits));
Screenshot of generated page:
-image::../img/dropdown-choice.png[]
+image::./img/dropdown-choice.png[]
In addition to the component id, in order to build a DropDownChoice we need to provide to its constructor two further parameters:
diff --git a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_6.adoc b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_6.adoc
index 5b68d4bacc..74904f5edd 100644
--- a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_6.adoc
+++ b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_6.adoc
@@ -5,7 +5,7 @@ Models that extend _org.apache.wicket.model.ChainingModel_ can be used to build
The example page will look like this:
-image::../img/model-chaining.png[]
+image::./img/model-chaining.png[]
What we want to do in this example is to chain the model of the DropDownChoice (which contains the selected Person) with the model of the Form. In this way the Form will work with the selected Person as backing object. The DropDownChoice component can be configured to automatically update its model each time we change the selected item on the client side. All we have to do is to add a FormComponentUpdatingBehavior to it: The behavior will submit the components value every time JavaScript [...]
diff --git a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_7.adoc b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_7.adoc
index 16c892037e..d284455de5 100644
--- a/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_7.adoc
+++ b/wicket-user-guide/src/main/asciidoc/modelsforms/modelsforms_7.adoc
@@ -1,7 +1,7 @@
-In chapter 6 we have seen how Wicket uses serialization to store page instances. When an object is serialized, all its referenced objects are recursively serialized. For a page this means that all its children components, their related models as well as the model objects inside them will be serialized.
+In chapter 6 we have seen how Wicket uses serialization to store page instances. When an object is serialized, all its referenced objects are recursively serialized. For a page this means that all its children components, their related models as well as the model objects inside them will be serialized.
For model objects this could be a serious issue for (at least) two main reasons:
1. The model object could be a very large instance, hence serialization would become very expensive in terms of time and memory.
@@ -9,16 +9,16 @@ For model objects this could be a serious issue for (at least) two main reasons:
To cope with these problems IModel extends another interface called IDetachable.
-image::../img/detachable-models.png[]
+image::./img/detachable-models.png[]
This interface provides a method called detach() which is invoked by Wicket at the end of web request processing when data model is no more needed but before serialization occurs. Overriding this method we can clean any reference to data object keeping just the information needed to retrieve it later (for example the id of the table row where our data are stored). In this way we can avoid the serialization of the object wrapped into the model overcoming both the problem with non-serializ [...]
-Since IModel inherits from IDetachable, every model of Wicket is “detachable”, although not all of them implement a detaching policy (like the Model class).
+Since IModel inherits from IDetachable, every model of Wicket is “detachable”, although not all of them implement a detaching policy (like the Model class).
Usually detaching operations are strictly dependent on the persistence technology adopted for model objects (like a relational db, a NoSQL db, a queue, etc), so it's not unusual to write a custom detachable model suited for the persistence technology chosen for a given project. To ease this task Wicket provides abstract model LoadableDetachableModel. This class internally holds a transient reference to a model object which is initialized the first time getObject() is called to process a [...]
The following class diagram summarizes the methods defined inside LoadableDetachableModel.
-image::../img/loadable-detachable-model.png[]
+image::./img/loadable-detachable-model.png[]
onDetach and onAttach can be overridden in order to obtain further control over the detaching procedure.
@@ -29,18 +29,18 @@ WARNING: The following model is provided for example purposes only and is not in
[source,java]
----
public class JpaLoadableModel<T> extends LoadableDetachableModel<T> {
-
+
private EntityManagerFactory entityManagerFactory;
private Class<T> entityClass;
private Serializable identifier;
private List<Object> constructorParams;
-
+
public JpaLoadableModel(EntityManagerFactory entityManagerFactory, T entity) {
-
+
super();
-
+
PersistenceUnitUtil util = entityManagerFactory.getPersistenceUnitUtil();
-
+
this.entityManagerFactory = entityManagerFactory;
this.entityClass = (Class<T>) entity.getClass();
this.identifier = (Serializable) util.getIdentifier(entity);
@@ -52,7 +52,7 @@ public class JpaLoadableModel<T> extends LoadableDetachableModel<T> {
protected T load() {
T entity = null;
- if(identifier != null) {
+ if(identifier != null) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
entity = entityManager.find(entityClass, identifier);
}
@@ -68,7 +68,7 @@ public class JpaLoadableModel<T> extends LoadableDetachableModel<T> {
if(entity == null) return;
- identifier = (Serializable) persistenceUtil.getIdentifier(entity);
+ identifier = (Serializable) persistenceUtil.getIdentifier(entity);
}
}
----
diff --git a/wicket-user-guide/src/main/asciidoc/monitoring/monitoring_2.adoc b/wicket-user-guide/src/main/asciidoc/monitoring/monitoring_2.adoc
index 73a9e2a04a..57e42b8a45 100644
--- a/wicket-user-guide/src/main/asciidoc/monitoring/monitoring_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/monitoring/monitoring_2.adoc
@@ -18,7 +18,7 @@ this.
[source,java]
----
private GraphiteReporter reporter;
-
+
@Override
protected void init()
{
@@ -27,7 +27,7 @@ this.
reporter = GraphiteReporter.forRegistry(metricRegistry).prefixedWith("WebApplications")
.convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS)
.filter(MetricFilter.ALL).build(graphite);
-
+
// Collects data every 5 seconds
reporter.start(5, TimeUnit.SECONDS);
}
@@ -42,8 +42,8 @@ this.
(3) Install and setup graphite on your system. Example installation for Mac (beware that this is only a quickstart setup!):
-- (1) Install homebrew: http://brew.sh/[brew]
-- (2) Install https://git-scm.com/[Git]
+- (1) Install homebrew: http://brew.sh/[brew]
+- (2) Install https://git-scm.com/[Git]
- (3) brew install python
@@ -53,14 +53,14 @@ this.
- (6) pip install Django==1.5
-- (7) pip install "django-tagging<0.4"
+- (7) pip install "django-tagging<0.4"
- (8) sudo pip install carbon
- (9) pip install whisper
- (10) sudo pip install graphite-web
-- (11) sudo pip install Twisted==11.1.0
+- (11) sudo pip install Twisted==11.1.0
- (12) sudo chown -R <your username>:staff /opt/graphite
@@ -80,9 +80,9 @@ this.
- (20) Go to http://localhost:8080
-* (18) and (19) have to be executed if the mac has been restarted
+* (18) and (19) have to be executed if the mac has been restarted
(4) Now start your tomcat server configured like mentioned in the previous chapter.
-image::../img/wicket_metrics_graphite.png[]
+image::./img/wicket_metrics_graphite.png[]
diff --git a/wicket-user-guide/src/main/asciidoc/redirects.adoc b/wicket-user-guide/src/main/asciidoc/redirects.adoc
index c48c47bd0f..240383350a 100644
--- a/wicket-user-guide/src/main/asciidoc/redirects.adoc
+++ b/wicket-user-guide/src/main/asciidoc/redirects.adoc
@@ -7,11 +7,11 @@ What does the default RenderStrategy actually do?
Both logical parts of a single HTTP request, an action and a render part get processed within the same request, but instead of streaming the render result to the browser directly, the result is cached on the server first.
-image::../img/lost-in-redirection-mockup.png[]
+image::./img/lost-in-redirection-mockup.png[]
Wicket will create an according BufferedHttpServletResponse instance that will be used to cache the resulting HttpServletResponse within the WebApplication.
-image::../img/lost-in-redirection-mockup2.png[]
+image::./img/lost-in-redirection-mockup2.png[]
After the buffered response is cached the HTTP status code of 302 gets provided back to the browser resulting in an additional GET request to the redirect URL (which Wicket sets to the URL of the Form itself). There is a special handling code for this case in the WicketFilter instance that then looks up a Map of buffered responses within the WebApplication accordingly. If an appropriate already cached response for the current request is found, it gets streamed back to the browser immedia [...]
@@ -55,7 +55,7 @@ So what happens in case you have 2 server running your application with session
Since a Map of buffered responses is cached within a WebApplication instance that does not get replicated between the nodes obviously, a redirect request that is suppose to pick up the previously cached response (having possibly form violation messages inside) potentially get’s directed to the second node in your cluster by the load balancer. The second node does not have any responses already prepared and cached for your user. The node therefore handles the request as a completely new r [...]
-image::../img/lost-in-redirection-mockup3.png[]
+image::./img/lost-in-redirection-mockup3.png[]
Unfortunately, there is currently no ideal solution to the problem described above. The default RenderStrategy used by Apache Wicket simply does not work well in a fully clustered environment with load balancing and session replication turned on. One possibility is to change the default render strategy for your application to a so called ONE_PASS_RENDER RenderStrategy which is the more suitable option to use when you want to do sophisticated (non-sticky session) clustering. This is easil [...]
@@ -72,6 +72,6 @@ ONE_PASS_RENDER RenderStrategy does not solve the double submit problem though!
You could of course turn on the session stickiness between your load balancer (apache server) and your tomcat server additionally to the session replication which would be the preferred solution in my opinion.
-image::../img/lost-in-redirection-mockup4.png[]
+image::./img/lost-in-redirection-mockup4.png[]
Session replication would still provide you with failover in case one of the tomcat server dies for whatever reason and sticky sessions would ensure that the Lost In Redirection problem does not occur any more.
diff --git a/wicket-user-guide/src/main/asciidoc/repeaters/repeaters_2.adoc b/wicket-user-guide/src/main/asciidoc/repeaters/repeaters_2.adoc
index 4108d41731..ebadf7682b 100644
--- a/wicket-user-guide/src/main/asciidoc/repeaters/repeaters_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/repeaters/repeaters_2.adoc
@@ -1,9 +1,9 @@
-As its name suggests, component _org.apache.wicket.markup.html.list.ListView_ is designed to display a given list of objects which can be provided as a standard Java List or as a model containing the concrete List. ListView iterates over the list and creates a child component of type _org.apache.wicket.markup.html.list.ListItem_ for every encountered item.
+As its name suggests, component _org.apache.wicket.markup.html.list.ListView_ is designed to display a given list of objects which can be provided as a standard Java List or as a model containing the concrete List. ListView iterates over the list and creates a child component of type _org.apache.wicket.markup.html.list.ListItem_ for every encountered item.
-Unlike RepeatingView this component is intended to be used with complex markup fragments containing nested components.
+Unlike RepeatingView this component is intended to be used with complex markup fragments containing nested components.
To generate its children, ListView calls its abstract method populateItem(ListItem<T> item) for each item in the list, so we must provide an implementation of this method to tell the component how to create its children components. In the following example we use a ListView to display a list of Person objects:
@@ -26,21 +26,21 @@ To generate its children, ListView calls its abstract method populateItem(ListIt
[source,java]
----
public HomePage(final PageParameters parameters) {
- List<Person> persons = Arrays.asList(new Person("John", "Smith"),
+ List<Person> persons = Arrays.asList(new Person("John", "Smith"),
new Person("Dan", "Wong"));
-
+
add(new ListView<Person>("persons", persons) {
@Override
protected void populateItem(ListItem<Person> item) {
item.add(new Label("fullName", new PropertyModel(item.getModel(), "fullName")));
- }
+ }
});
}
----
*Screenshot of generated page:*
-image::../img/simple-listview-screenshot.png[]
+image::./img/simple-listview-screenshot.png[]
In this example we have displayed the full name of two Person's instances. The most interesting part of the code is the implementation of method populateItem where parameter item is the current child component created by ListView and its model contains the corresponding element of the list. Please note that inside populateItem we must add nested components to the _item_ object and not directly to the _ListView_.
diff --git a/wicket-user-guide/src/main/asciidoc/repeaters/repeaters_4.adoc b/wicket-user-guide/src/main/asciidoc/repeaters/repeaters_4.adoc
index 7e1f2a5f88..c641032c1b 100644
--- a/wicket-user-guide/src/main/asciidoc/repeaters/repeaters_4.adoc
+++ b/wicket-user-guide/src/main/asciidoc/repeaters/repeaters_4.adoc
@@ -1,15 +1,15 @@
-Wicket offers a number of components that should be used when we have to display a big number of items (for example the results of a select SQL query).
+Wicket offers a number of components that should be used when we have to display a big number of items (for example the results of a select SQL query).
-All these components implement interface _org.apache.wicket.markup.html.navigation.paging.IPageable_ and use interface _IDataProvider_ (placed in package _org.apache.wicket.markup.repeater.data_) as data source. This interface is designed to support data paging. We will see an example of data paging later in <<repeaters.adoc#_pageable_repeaters,paragraph 13.4.2>>.
+All these components implement interface _org.apache.wicket.markup.html.navigation.paging.IPageable_ and use interface _IDataProvider_ (placed in package _org.apache.wicket.markup.repeater.data_) as data source. This interface is designed to support data paging. We will see an example of data paging later in <<repeaters.adoc#_pageable_repeaters,paragraph 13.4.2>>.
The methods defined by IDataProvider are the following:
* *iterator(long first, long count):* returns an iterator over a subset of the entire dataset. The subset starts from the item at position first and includes all the next count items (i.e. it's the closed interval <<_first,first+count>>
).
-* *size():* gets the size of the entire dataset.
+* *size():* gets the size of the entire dataset.
* *model(T object):* this method is used to wrap an item returned by the iterator with a model. This can be necessary if, for example, we need to wrap items with a detachable model to prevent them from being serialized.
Wicket already provides implementations of IDataProvider to work with a List as data source (ListDataProvider) and to support data sorting (SortableDataProvider).
@@ -39,7 +39,7 @@ List<Person> persons = loadPersons();
ListDataProvider<Person> listDataProvider = new ListDataProvider<Person>(persons);
DataView<Person> dataView = new DataView<Person>("rows", listDataProvider) {
-
+
@Override
protected void populateItem(Item<Person> item) {
Person person = item.getModelObject();
@@ -47,15 +47,15 @@ DataView<Person> dataView = new DataView<Person>("rows", listDataProvider) {
repeatingView.add(new Label(repeatingView.newChildId(), person.getName()));
repeatingView.add(new Label(repeatingView.newChildId(), person.getSurname()));
- repeatingView.add(new Label(repeatingView.newChildId(), person.getAddress()));
+ repeatingView.add(new Label(repeatingView.newChildId(), person.getAddress()));
repeatingView.add(new Label(repeatingView.newChildId(), person.getEmail()));
- item.add(repeatingView);
+ item.add(repeatingView);
}
};
add(dataView);
----
-Please note that in the code above we have used also a RepeatingView component to populate the rows of the table.
+Please note that in the code above we have used also a RepeatingView component to populate the rows of the table.
In the next paragraph we will see a similar example that adds support for data paging.
@@ -63,7 +63,7 @@ In the next paragraph we will see a similar example that adds support for data p
To enable data paging on a pageable repeater, we must first set the number of items to display per page with method setItemsPerPage(long items). Then, we must attach the repeater to panel PagingNavigator (placed in package _org.apache.wicket.markup.html.navigation.paging_) which is responsible for rendering a navigation bar containing the links illustrated in the following picture:
-image::../img/paging-navigator.png[]
+image::./img/paging-navigator.png[]
Project PageDataViewExample mixes a DataView component with a PagingNavigator to display the list of all countries of the world sorted by alphabetical order. Here is the initialization code of the project home page:
@@ -89,28 +89,28 @@ public HomePage(final PageParameters parameters) {
//It reads countries data from a csv file and returns each row as an array of Strings.
List<String[]> countries = loadCountriesFromCsv();
ListDataProvider<String[]> listDataProvider = new ListDataProvider<String[]>(countries);
-
+
DataView<String[]> dataView = new DataView<String[]>("rows", listDataProvider) {
@Override
protected void populateItem(Item<String[]> item) {
String[] countriesArr = item.getModelObject();
RepeatingView repeatingView = new RepeatingView("dataRow");
-
+
for (int i = 0; i < countriesArr.length; i++){
repeatingView.add(new Label(repeatingView.newChildId(), countriesArr[i]));
}
item.add(repeatingView);
}
};
-
+
dataView.setItemsPerPage(15);
-
+
add(dataView);
add(new PagingNavigator("pagingNavigator", dataView));
}
----
-The data of a single country (ISO code, name, long name, capital and population) are handled with an array of strings. The usage of PagingNavigator is quite straightforward as we need to simply pass the pageable repeater to its constructor.
+The data of a single country (ISO code, name, long name, capital and population) are handled with an array of strings. The usage of PagingNavigator is quite straightforward as we need to simply pass the pageable repeater to its constructor.
To explore the other pageable repeaters shipped with Wicket you can visit the {wicket_examples_url}/repeater[examples site] where you can find live examples of these components.
diff --git a/wicket-user-guide/src/main/asciidoc/requestProcessing/requestProcessing_3.adoc b/wicket-user-guide/src/main/asciidoc/requestProcessing/requestProcessing_3.adoc
index 5d07291bd8..85dc4ce5a7 100644
--- a/wicket-user-guide/src/main/asciidoc/requestProcessing/requestProcessing_3.adoc
+++ b/wicket-user-guide/src/main/asciidoc/requestProcessing/requestProcessing_3.adoc
@@ -28,7 +28,7 @@ To resolve the right handler for a given HTTP request, the _RequestCycle_ uses a
The following sequence diagram recaps how a request handler is resolved by the _RequestCycle_:
-image::../img/request-cycle-handler.png[]
+image::./img/request-cycle-handler.png[]
Developers can create additional implementations of _IRequestMapper_ and add them to their application via the _mount(IRequestMapper mapper)_ method of the _WebApplication_ class. In paragraph 10.6 we will see how Wicket uses this method to add built-in mappers for mounted pages.
diff --git a/wicket-user-guide/src/main/asciidoc/requestProcessing/requestProcessing_4.adoc b/wicket-user-guide/src/main/asciidoc/requestProcessing/requestProcessing_4.adoc
index e5ede08a05..38c7bba162 100644
--- a/wicket-user-guide/src/main/asciidoc/requestProcessing/requestProcessing_4.adoc
+++ b/wicket-user-guide/src/main/asciidoc/requestProcessing/requestProcessing_4.adoc
@@ -48,7 +48,7 @@ HttpSession session = ((ServletWebRequest)RequestCycle.get()
Using the raw session object might be necessary if we have to set a session attribute with a particular name without the prefix added by Wicket. Let's say for example that we are working with Tomcat as web server. One of the administrative tools provided by Tomcat is a page listing all the active user sessions of a given web application:
-image::../img/tomcat-admin-sessions.png[]
+image::./img/tomcat-admin-sessions.png[]
Tomcat allows us to set the values that will be displayed in columns “Guessed locale” and “Guessed User name”. One possible way to do this is to use session attributes named “Locale” and “userName” but we can't create them via Wicket's Session class because they would not have exactly the name required by Tomcat. Instead, we must use the raw _HttpSession_ and set our attributes on it:
diff --git a/wicket-user-guide/src/main/asciidoc/resources/resources_14.adoc b/wicket-user-guide/src/main/asciidoc/resources/resources_14.adoc
index 13d5246ebb..1248d12d3c 100644
--- a/wicket-user-guide/src/main/asciidoc/resources/resources_14.adoc
+++ b/wicket-user-guide/src/main/asciidoc/resources/resources_14.adoc
@@ -7,23 +7,23 @@ Wicket loads application's resources delegating this task to a resource locator
----
//init application's method
@Override
- public void init(){
- //get the resource locator
+ public void init(){
+ //get the resource locator
getResourceSettings().getResourceStreamLocator();
- //set the resource locator
+ //set the resource locator
getResourceSettings().setResourceStreamLocator(myLocator);
}
----
The default locator used by Wicket is class _ResourceStreamLocator_ which in turn tries to load a requested resource using a set of implementations of interface _IResourceFinder_. This interface defines method _find(Class class, String pathname)_ which tries to resolve a resource corresponding to the given class and path.
-The default implementation of _IResourceFinder_ used by Wicket is _ClassPathResourceFinder_ which searches for resources into the application class path. This is the implementation we have used so far in our examples. However some developers may prefer storing markup files and other resources in a separate folder rather than placing them side by side with Java classes.
+The default implementation of _IResourceFinder_ used by Wicket is _ClassPathResourceFinder_ which searches for resources into the application class path. This is the implementation we have used so far in our examples. However some developers may prefer storing markup files and other resources in a separate folder rather than placing them side by side with Java classes.
To customize resource loading we can add further resource finders to our application in order to extend the resource-lookup algorithm to different locations. Wicket already comes with two other implementations of IResourceFinder designed to search for resources into a specific folder on the file system. The first is class _Path_ and it's defined in package _org.apache.wicket.util.file_. The constructor of this class takes in input an arbitrary folder that can be expressed as a string pat [...]
Project CustomFolder4MarkupExample uses _WebApplicationPath_ to load the markup file and the resource bundle for its home page from a custom folder. The folder is called markupFolder and it is placed in the root path of the webapp. The following picture illustrates the file structure of the project:
-image::../img/package-structure-custom-folder.png[]
+image::./img/package-structure-custom-folder.png[]
As we can see in the picture above, we must preserve the package structure also in the custom folder used as resource container. The code used inside application class to configure WebApplicationPath is the following:
@@ -41,7 +41,7 @@ Method getResourceFinders() defined by setting class ResourceSettings returns th
NOTE: By default, if resource files can not be found inside application classpath, Wicket will search for them inside “resources” folder. You may have noted this folder in the previous picture. It is placed next to the folder “java” containing our source files:
-image::../img/package-structure-resource-folder.png[]
+image::./img/package-structure-resource-folder.png[]
This folder can be used to store resource files without writing any configuration code.
diff --git a/wicket-user-guide/src/main/asciidoc/resources/resources_3.adoc b/wicket-user-guide/src/main/asciidoc/resources/resources_3.adoc
index 6a4bc3eb3e..8161379264 100644
--- a/wicket-user-guide/src/main/asciidoc/resources/resources_3.adoc
+++ b/wicket-user-guide/src/main/asciidoc/resources/resources_3.adoc
@@ -5,17 +5,17 @@ With HTML we use to include static resources in our pages using tags like <scrip
To solve this problem Wicket allows us to place static resource files into component package (like we do with markup and properties files) and load them from component code.
-These kinds of resources are called package resources (a CSS and a JavaScript file in this screenshot):
+These kinds of resources are called package resources (a CSS and a JavaScript file in this screenshot):
-image::../img/package-resources.png[]
+image::./img/package-resources.png[]
With package resources custom components become independent and self-contained and client code can use them without worrying about their dependencies.
-To load package resources Wicket provides class _org.apache.wicket.request.resource.PackageResourceReference_.
+To load package resources Wicket provides class _org.apache.wicket.request.resource.PackageResourceReference_.
-To identify a package resource we need to specify a class inside the target package and the name of the desired resource (most of the times this will be a file name).
+To identify a package resource we need to specify a class inside the target package and the name of the desired resource (most of the times this will be a file name).
-In the following example taken from project ImageAsPackageRes, CustomPanel loads a picture file available as package resource and it displays it in a <img> tag using the built-in component _org.apache.wicket.markup.html.image.Image_:
+In the following example taken from project ImageAsPackageRes, CustomPanel loads a picture file available as package resource and it displays it in a <img> tag using the built-in component _org.apache.wicket.markup.html.image.Image_:
*HTML:*
[source,html]
@@ -37,7 +37,7 @@ public class CustomPanel extends Panel {
public CustomPanel(String id) {
super(id);
- PackageResourceReference resourceReference =
+ PackageResourceReference resourceReference =
new PackageResourceReference(getClass(), "calendar.jpg");
add(new Image("packageResPicture", resourceReference));
}
@@ -52,17 +52,17 @@ In our example the URL for our picture file calendar.jpg is the following:
_./wicket/resource/org.wicketTutorial.CustomPanel/calendar-ver-1297887542000.jpg_
-The first part of the URL is the relative path to the application root. In our example our page is already at the application's root so we have only a single-dotted segment. The next two segments, wicket and resource, are respectively the namespace and the identifier for resources seen in <<urls.adoc#_generating_structured_and_clear_urls,paragraph 10.6.4>>.
+The first part of the URL is the relative path to the application root. In our example our page is already at the application's root so we have only a single-dotted segment. The next two segments, wicket and resource, are respectively the namespace and the identifier for resources seen in <<urls.adoc#_generating_structured_and_clear_urls,paragraph 10.6.4>>.
The fourth segment is the fully qualified name of the class used to locate the resource and it is the scope of the package resource. In the last segment of the URL we can find the name of the resource (the file name).
-As you can see Wicket has automatically appended to the file name a version identifier (ver-1297887542000). When Wicket runs in DEVELOPMENT mode this identifier contains the timestamp in millisecond indicating the last time the resource file was modified. This can be useful when we are developing our application and resource files are frequently modified. Appending the timestamp to the original name we are sure that our browser will use always the last version of the file and not an old, [...]
+As you can see Wicket has automatically appended to the file name a version identifier (ver-1297887542000). When Wicket runs in DEVELOPMENT mode this identifier contains the timestamp in millisecond indicating the last time the resource file was modified. This can be useful when we are developing our application and resource files are frequently modified. Appending the timestamp to the original name we are sure that our browser will use always the last version of the file and not an old, [...]
-When instead Wicket is running in DEPLOYMENT mode, the version identifier will contain the MD5 digest of the file instead of the timestamp. The digest is computed only the first time the resource is requested. This perfectly makes sense as static resources don't change so often when our application runs into production environment and when this appends the application is redeployed.
+When instead Wicket is running in DEPLOYMENT mode, the version identifier will contain the MD5 digest of the file instead of the timestamp. The digest is computed only the first time the resource is requested. This perfectly makes sense as static resources don't change so often when our application runs into production environment and when this appends the application is redeployed.
NOTE: Package resources can be localized following the same rules seen for resource bundles and markup files:
-image::../img/package-resource-localization.png[]
+image::./img/package-resource-localization.png[]
In the example illustrated in the picture above, if we try to retrieve package resource calendar.jpg when the current locale is set to French, the actual file returned will be calendar_fr.jpg.
@@ -82,8 +82,8 @@ Since Wicket 7.0.0 the build-in component _org.apache.wicket.markup.html.image.I
[source,java]
----
...
- Image image = new Image("packageResPicture",
- new PackageResourceReference(getClass(),"small.jpg"),
+ Image image = new Image("packageResPicture",
+ new PackageResourceReference(getClass(),"small.jpg"),
new PackageResourceReference(getClass(), "large.jpg"),
new PackageResourceReference(getClass(), "medium.jpg"),
new PackageResourceReference(getClass(), "small.jpg"));
@@ -117,7 +117,7 @@ The component _org.apache.wicket.markup.html.image.Picture_ is used to provide a
Source big = new Source("big", new PackageResourceReference(getClass(), "big.jpg"), new PackageResourceReference(getClass(), "big-hd.jpg");
big.setXValues("1x","2x");
big.setMedia("(min-width: 40em)");
- picture.add(big);
+ picture.add(big);
Source small = new Source("small", new PackageResourceReference(getClass(), "small.jpg"), new PackageResourceReference(getClass(), "small-hd.jpg");
small.setXValues("1x","2x");
diff --git a/wicket-user-guide/src/main/asciidoc/security/security_1.adoc b/wicket-user-guide/src/main/asciidoc/security/security_1.adoc
index 33d454af80..69b6919f3d 100644
--- a/wicket-user-guide/src/main/asciidoc/security/security_1.adoc
+++ b/wicket-user-guide/src/main/asciidoc/security/security_1.adoc
@@ -3,7 +3,7 @@
The first step in implementing a security policy is assigning a trusted identity to our users, which means that we must authenticate them. Web applications usually adopt a form-based authentication with a login form that asks user for a unique username and the relative password:
-image::../img/wikipedia-login-form.png[]
+image::./img/wikipedia-login-form.png[]
Wicket supports form-based authentication with session class _AuthenticatedWebSession_ and application class _AuthenticatedWebApplication_, both placed inside package _org.apache.wicket.authroles.authentication_.
@@ -46,7 +46,7 @@ public class AuthenticatedPage extends WebPage {
if(!AuthenticatedWebSession.get().isSignedIn())
app.restartResponseAtSignInPage();
}
-
+
@Override
protected void onInitialize() {
super.onInitialize();
@@ -64,7 +64,7 @@ public class AuthenticatedPage extends WebPage {
}
----
-Page _AuthenticatedPage_ checks inside onConfigure if user is signed in and if not, it redirects her/him to the sign in page with method _restartResponseAtSignInPage_. The page contains also a link to the homepage and another link that signs out user.
+Page _AuthenticatedPage_ checks inside onConfigure if user is signed in and if not, it redirects her/him to the sign in page with method _restartResponseAtSignInPage_. The page contains also a link to the homepage and another link that signs out user.
The sign in page is implemented in class _SignInPage_ and contains the form used to authenticate users:
@@ -73,29 +73,29 @@ The sign in page is implemented in class _SignInPage_ and contains the form used
public class SignInPage extends WebPage {
private String username;
private String password;
-
+
@Override
protected void onInitialize() {
super.onInitialize();
-
+
StatelessForm<Void> form = new StatelessForm<Void>("form") {
@Override
protected void onSubmit() {
if(Strings.isEmpty(username))
return;
-
+
boolean authResult = AuthenticatedWebSession.get().signIn(username, password);
//if authentication succeeds redirect user to the requested page
if(authResult)
continueToOriginalDestination();
}
};
-
+
form.setModel(new CompoundPropertyModel(this));
-
+
form.add(new TextField("username"));
form.add(new PasswordTextField("password"));
-
+
add(form);
}
}
diff --git a/wicket-user-guide/src/main/asciidoc/security/security_2.adoc b/wicket-user-guide/src/main/asciidoc/security/security_2.adoc
index 3bc775fcce..5bc1b116ae 100644
--- a/wicket-user-guide/src/main/asciidoc/security/security_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/security/security_2.adoc
@@ -10,7 +10,7 @@ public interface IAuthorizationStrategy {
//interface methods
<T extends IRequestableComponent> boolean isInstantiationAuthorized(Class<T> componentClass);
boolean isActionAuthorized(Component component, Action action);
-
+
//default authorization strategy that allows everything
public static final IAuthorizationStrategy ALLOW_ALL = new IAuthorizationStrategy()
{
@@ -39,7 +39,7 @@ To change the authorization strategy in use we must register the desired impleme
[source,java]
----
- //Application class code...
+ //Application class code...
@Override
public void init()
{
@@ -60,7 +60,7 @@ Abstract class SimplePageAuthorizationStrategy (in package _org.apache.wicket.au
[source,java]
----
-SimplePageAuthorizationStrategy authorizationStrategy = new SimplePageAuthorizationStrategy(
+SimplePageAuthorizationStrategy authorizationStrategy = new SimplePageAuthorizationStrategy(
PageClassToCheck.class, SignInPage.class)
{
protected boolean isAuthorized()
@@ -84,7 +84,7 @@ The session class in the following example returns a custom “SIGNED_IN” role
----
class BasicAuthenticationRolesSession extends AuthenticatedWebSession {
private String userName;
-
+
public BasicAuthenticationRolesSession(Request request) {
super(request);
}
@@ -92,25 +92,25 @@ class BasicAuthenticationRolesSession extends AuthenticatedWebSession {
@Override
public boolean authenticate(String username, String password) {
boolean authResult= false;
-
+
authResult = //some authentication logic...
-
+
if(authResult)
userName = username;
-
+
return authResult;
}
@Override
public Roles getRoles() {
Roles resultRoles = new Roles();
-
+
if(isSignedIn())
resultRoles.add("SIGNED_IN");
-
+
if(userName.equals("superuser"))
resultRoles.add(Roles.ADMIN);
-
+
return resultRoles;
}
}
@@ -139,7 +139,7 @@ public class WicketApplication extends AuthenticatedWebApplication {
public Class<? extends WebPage> getHomePage(){
return HomePage.class;
}
-
+
@Override
protected Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass() {
return BasicAuthenticationSession.class;
@@ -149,9 +149,9 @@ public class WicketApplication extends AuthenticatedWebApplication {
protected Class<? extends WebPage> getSignInPageClass() {
return SignInPage.class;
}
-
+
@Override
- public void init(){
+ public void init(){
getSecuritySettings().setAuthorizationStrategy(new MetaDataRoleAuthorizationStrategy(this));
MetaDataRoleAuthorizationStrategy.authorize(AdminOnlyPage.class, Roles.ADMIN);
}
@@ -167,17 +167,17 @@ public class BasicAuthenticationSession extends AuthenticatedWebSession {
private String username;
public BasicAuthenticationSession(Request request) {
- super(request);
+ super(request);
}
@Override
public boolean authenticate(String username, String password) {
//user is authenticated if username and password are equal
boolean authResult = username.equals(password);
-
+
if(authResult)
this.username = username;
-
+
return authResult;
}
@@ -189,10 +189,10 @@ public class BasicAuthenticationSession extends AuthenticatedWebSession {
//if username is equal to 'superuser' add the ADMIN role
if(username!= null && username.equals("superuser"))
resultRoles.add(Roles.ADMIN);
-
+
return resultRoles;
}
-
+
@Override
public void signOut() {
super.signOut();
@@ -209,7 +209,7 @@ The code from session class has three interesting methods. The first is _authent
Now if we run the project and we try to access to _AdminOnlyPage_ from the home page without having the ADMIN role, we will be redirected to the default access-denied page used by Wicket:
-image::../img/authorization-access-denied.png[]
+image::./img/authorization-access-denied.png[]
The access-denied page can be customized using method _setAccessDeniedPage(Class<? extends Page>)_ of setting class _ApplicationSettings_:
@@ -217,9 +217,9 @@ The access-denied page can be customized using method _setAccessDeniedPage(Class
----
//Application class code...
@Override
- public void init(){
+ public void init(){
getApplicationSettings().setAccessDeniedPage(
- MyCustomAccessDeniedPage.class);
+ MyCustomAccessDeniedPage.class);
}
----
@@ -260,13 +260,13 @@ This listener must be registered into application's security settings with metho
[source,java]
----
-public class WicketApplication extends AuthenticatedWebApplication{
+public class WicketApplication extends AuthenticatedWebApplication{
//Application code...
@Override
- public void init(){
+ public void init(){
getSecuritySettings().setUnauthorizedComponentInstantiationListener(
new IUnauthorizedComponentInstantiationListener() {
-
+
@Override
public void onUnauthorizedInstantiation(Component component) {
component.setResponsePage(AuthWarningPage.class);
diff --git a/wicket-user-guide/src/main/asciidoc/testing/testing_1.adoc b/wicket-user-guide/src/main/asciidoc/testing/testing_1.adoc
index 35daf7e089..0bae61e2df 100644
--- a/wicket-user-guide/src/main/asciidoc/testing/testing_1.adoc
+++ b/wicket-user-guide/src/main/asciidoc/testing/testing_1.adoc
@@ -3,7 +3,7 @@
A good way to start getting confident with Wicket unit testing support is looking at the test case class _TestHomePage_ that is automatically generated by Maven when we use Wicket archetype to create a new project:
-image::../img/mvn-wicket-archetype.png[]
+image::./img/mvn-wicket-archetype.png[]
Here is the content of TestHomePage:
@@ -54,14 +54,14 @@ public void switchLabelTest(){
//simulate a click on "reload" button
tester.clickLink("reload");
//assert rendered label
- tester.assertLabel("label", "Second label");
+ tester.assertLabel("label", "Second label");
}
//...
----
In the code above we have used _clickLink_ to click on the "reload" button and force page to be rendered again. In addition, we have used also method _assertLabel_ that checks if a given label contains the expected text.
-By default _clickLink_ assumes that AJAX is enabled on client side. To switch AJAX off we can use another version of this method that takes in input the path to the link component and a boolean flag that indicates if AJAX must be enabled (true) or not (false).
+By default _clickLink_ assumes that AJAX is enabled on client side. To switch AJAX off we can use another version of this method that takes in input the path to the link component and a boolean flag that indicates if AJAX must be enabled (true) or not (false).
[source,java]
----
@@ -79,7 +79,7 @@ WicketTester provides also a set of methods to test the states of a component. T
* *assertVisible(String path)/assertInvisible(String path)*: they test component visibility.
* *assertRequired(String path)*: checks if a form component is required.
-In the test case from project _CustomDatepickerAjax_ we used _assertEnabled_/_assertDisabled_ to check if button "update" really disables our datepicker:
+In the test case from project _CustomDatepickerAjax_ we used _assertEnabled_/_assertDisabled_ to check if button "update" really disables our datepicker:
[source,java]
----
@@ -93,7 +93,7 @@ public void testDisableDatePickerWithButton(){
//click on update button to disable datepicker
tester.clickLink("update");
//assert that datepicker is disabled
- tester.assertDisabled("form:datepicker");
+ tester.assertDisabled("form:datepicker");
}
//...
----
@@ -120,7 +120,7 @@ public void testCustomPanelContainsLabel(){
_WicketTester_ allows us to access to the last response generated during testing with method _getLastResponse()_. The returned value is an instance of class MockHttpServletResponse that provides helper methods to extract information from mocked request.
-In the test case from project _CustomResourceMounting_ we extract the text contained in the last response with method _getDocument_ and we check if it is equal to the RSS feed used for the test:
+In the test case from project _CustomResourceMounting_ we extract the text contained in the last response with method _getDocument_ and we check if it is equal to the RSS feed used for the test:
[source,java]
----
@@ -132,9 +132,9 @@ public void testMountedResourceResponse() throws IOException, FeedException{test
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
SyndFeedOutput output = new SyndFeedOutput();
-
+
output.output(RSSProducerResource.getFeed(), writer);
- //the response and the RSS must be equal
+ //the response and the RSS must be equal
Assert.assertEquals(responseTxt, outputStream.toString());
}
//...
@@ -152,7 +152,7 @@ _WicketTester_ can be pointed to an arbitrary URL with method _executeUrl(String
----
//...
//the resource was mapped at '/foo/bar'
-tester.executeUrl("./foo/bar");
+tester.executeUrl("./foo/bar");
//...
----
@@ -164,7 +164,7 @@ If our application uses AJAX to refresh components markup, we can test if _AjaxR
----
//...
//test if AjaxRequestTarget contains a component (using its instance)
-tester.assertComponentOnAjaxResponse(amountLabel);
+tester.assertComponentOnAjaxResponse(amountLabel);
//...
//test if AjaxRequestTarget contains a component (using its path)
tester.assertComponentOnAjaxResponse("pathToLabel:labelId");
@@ -175,8 +175,8 @@ It's also possible to use method _isComponentOnAjaxResponse(Component cmp)_ to k
[source,java]
----
//...
-//test if AjaxRequestTarget does NOT contain amountLabel
-assertFalse(tester.isComponentOnAjaxResponse(amountLabel));
+//test if AjaxRequestTarget does NOT contain amountLabel
+assertFalse(tester.isComponentOnAjaxResponse(amountLabel));
//...
----
@@ -191,13 +191,13 @@ Behavior _AjaxEventBehavior_ and its subclasses can be tested simulating AJAX ev
public class HomePage extends WebPage {
public static String INIT_VALUE = "Initial value";
public static String OTHER_VALUE = "Other value";
-
+
public HomePage(final PageParameters parameters) {
super(parameters);
Label label;
- add(label = new Label("label", INIT_VALUE));
+ add(label = new Label("label", INIT_VALUE));
label.add(new AjaxEventBehavior("click") {
-
+
@Override
protected void onEvent(AjaxRequestTarget target) {
//change label's data object
@@ -220,7 +220,7 @@ public void testAjaxBehavior(){
//start and render the test page
tester.startPage(HomePage.class);
//test if label has the initial expected value
- tester.assertLabel("label", HomePage.INIT_VALUE);
+ tester.assertLabel("label", HomePage.INIT_VALUE);
//simulate an AJAX "click" event
tester.executeAjaxEvent("label", "click");
//test if label has changed as expected
@@ -235,23 +235,23 @@ To test a generic AJAX behavior we can simulate a request to it using _WicketTes
[source,java]
----
//...
-AjaxFormComponentUpdatingBehavior ajaxBehavior =
+AjaxFormComponentUpdatingBehavior ajaxBehavior =
new AjaxFormComponentUpdatingBehavior("change"){
@Override
protected void onUpdate(AjaxRequestTarget target) {
- //...
+ //...
}
};
component.add(ajaxBehavior);
//...
-//execute AJAX behavior, i.e. onUpdate will be invoked
-tester.executeBehavior(ajaxBehavior));
+//execute AJAX behavior, i.e. onUpdate will be invoked
+tester.executeBehavior(ajaxBehavior));
//...
----
=== Using a custom servlet context
-In <<resources_13.adoc,paragraph 16.13>> we have seen how to configure our application to store resource files into a custom folder placed inside webapp root folder (see project _CustomFolder4MarkupExample_).
+In <<resources_13.adoc,paragraph 16.13>> we have seen how to configure our application to store resource files into a custom folder placed inside webapp root folder (see project _CustomFolder4MarkupExample_).
In order to write testing code for applications that use this kind of customization, we must tell _WicketTester_ which folder to use as webapp root. This is necessary as under test environment we don't have any web server, hence it's impossible for _WicketTester_ to retrieve this parameter from servlet context.
@@ -264,10 +264,10 @@ public class TestHomePage{
@Before
public void setUp(){
- //build the path to webapp root folder
+ //build the path to webapp root folder
File curDirectory = new File(System.getProperty("user.dir"));
File webContextDir = new File(curDirectory, "src/main/webapp");
-
+
tester = new WicketTester(new WicketApplication(), webContextDir.getAbsolutePath());
}
//test methods...
@@ -313,7 +313,7 @@ public class TestHomePage
tester.addRequestHeader(SEC_FETCH_SITE_HEADER, SAME_SITE);
tester.clickLink("click");
}
-}
+}
----
-NOTE: keep in mind that request headers are immediately discarded after the use and thus are not re-used for following requests.
+NOTE: keep in mind that request headers are immediately discarded after the use and thus are not re-used for following requests.
diff --git a/wicket-user-guide/src/main/asciidoc/testingspring/testingspring_2.adoc b/wicket-user-guide/src/main/asciidoc/testingspring/testingspring_2.adoc
index 4175c17de4..edd8f0c5c9 100644
--- a/wicket-user-guide/src/main/asciidoc/testingspring/testingspring_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/testingspring/testingspring_2.adoc
@@ -63,7 +63,7 @@ java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoade
As you can see above, the Exception gets raised during the initialization of the _WicketTester_ instance even before the actual test method gets executed. Even though we have applied rather cool and simple annotation based test configuration already described and passed in perfectly well prepared ApplicationContext instance to the WicketTester instance in the constructor, somewhere down the rabbit hole someone complained that no WebApplicationContext instance could have been found which [...]
-image::../img/description-of-illegalstate.jpg[]
+image::./img/description-of-illegalstate.jpg[]
The problem that we run against here is due to the fact that SpringComponentInjector during its own initialization is trying to get hold of an according Spring's ApplicationContext instance that would normally be there in a runtime environment but does not find any since we are running in a test environment currently. SpringComponentInjector delegates to Spring's own WebApplicationContextUtils class to retrieve the instance of ApplicationContext out of the ServletContext which is perfect [...]
@@ -135,5 +135,5 @@ public class MyWebApplication extends WebApplication implements ApplicationConte
For additional clarification of how _MyWebApplication_ now relates to both Wicket and Spring framework here is an according class diagram:
-image::../img/mywebapp-class-diagramm.jpg[]
+image::./img/mywebapp-class-diagramm.jpg[]
diff --git a/wicket-user-guide/src/main/asciidoc/urls/urls_6.adoc b/wicket-user-guide/src/main/asciidoc/urls/urls_6.adoc
index c4323458c2..f3cbf2798b 100644
--- a/wicket-user-guide/src/main/asciidoc/urls/urls_6.adoc
+++ b/wicket-user-guide/src/main/asciidoc/urls/urls_6.adoc
@@ -54,7 +54,7 @@ Java code:
----
PageParameters pageParameters = new PageParameters();
pageParameters.add("foo", "foo");
-
+
setResponsePage(MountedPageWithPlaceholder.class, pageParameters)
----
@@ -125,7 +125,7 @@ Interface _org.apache.wicket.request.mapper.IMapperContext_ is used by request m
* Namespace: it's the first URL segment of non-mounted pages. By default its value is wicket.
* Identifier for non-bookmarkable URLs: it's the segment that identifies non bookmarkable pages. By default its value is page.
* Identifier for bookmarkable URLs: it's the segment that identifies bookmarkable pages. By default its value is bookmarkable (as we have seen before in <<urls.adoc#_pageparameters,paragraph 10.1.1>>).
-* Identifier for resources: it's the segment that identifies Wicket resources. Its default value is resources. The topic of resource management will be covered in
+* Identifier for resources: it's the segment that identifies Wicket resources. Its default value is resources. The topic of resource management will be covered in
<<_resource_management_with_wicket,chapter 16>>.
IMapperContext provides a getter method for any segment listed above. By default Wicket uses class _org.apache.wicket.DefaultMapperContext_ as mapper context.
@@ -185,11 +185,11 @@ add(new Link<Void>("mountedPage") {
@Override
public void onClick() {
-
+
PageParameters pageParameters = new PageParameters();
pageParameters.add("foo", "foo");
pageParameters.add("bar", "bar");
-
+
setResponsePage(MountedPage.class, pageParameters);
}
});
@@ -208,7 +208,7 @@ Sometimes URLs are a double–edged sword for our site because they can expose t
To avoid this kind of security threat we can use the _CryptoMapper_ request mapper which wraps an existing mapper and encrypts the original URL producing a single encrypted segment:
-image::../img/url-encrypted.png[]
+image::./img/url-encrypted.png[]
Typically, _CryptoMapper_ is registered into a Wicket application as the root request mapper wrapping the default one:
@@ -217,13 +217,13 @@ Typically, _CryptoMapper_ is registered into a Wicket application as the root re
@Override
public void init() {
super.init();
- setRootRequestMapper(new CryptoMapper(getRootRequestMapper(), this));
+ setRootRequestMapper(new CryptoMapper(getRootRequestMapper(), this));
//pages and resources must be mounted after we have set CryptoMapper
mountPage("/foo/", HomePage.class);
----
As pointed out in the code above, pages and resources must be mounted after having set _CryptoMapper_ as root mapper, otherwise the mounted paths will not work.
-WARNING: By default _CryptoMapper_ encrypts page URLs with a cipher that might not be strong enough for production environment. Paragraph
+WARNING: By default _CryptoMapper_ encrypts page URLs with a cipher that might not be strong enough for production environment. Paragraph
<<_security_with_wicket,"Security with Wicket">> will provide a more detailed description of how Wicket encrypts page URLs and we will see how to use stronger ciphers.
diff --git a/wicket-user-guide/src/main/asciidoc/versioningCaching/versioningCaching_2.adoc b/wicket-user-guide/src/main/asciidoc/versioningCaching/versioningCaching_2.adoc
index a2e1887fd6..e118ce4da4 100644
--- a/wicket-user-guide/src/main/asciidoc/versioningCaching/versioningCaching_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/versioningCaching/versioningCaching_2.adoc
@@ -7,7 +7,7 @@ A new page version is created when a stateful page is requested for the first ti
In the final example of the previous chapter (project LifeCycleStages), you may have noticed the number appended at the end of URL. This number is the page id we are talking about:
-image::../img/page-id.png[]
+image::./img/page-id.png[]
In this chapter we will use a revised version of this example project where the component hierarchy is modified inside the Link's _onClick()_ method. This is necessary because Wicket creates a new page version only if the page is modified before its method _onBeforeRender()_ is invoked. The code of the new home page is the following:
@@ -41,11 +41,11 @@ public class HomePage extends WebPage
Now if we run the new example (project LifeCycleStagesRevisited) and we click on the “Reload” button, a new page version is created and the page id is increased by one:
-image::../img/reload-page.png[]
+image::./img/reload-page.png[]
If we press the back button the page version previously rendered (and serialized) will be retrieved (i.e. deserialized) and it will be used again to respond to our request (and page id is decremented):
-image::../img/browser-back.png[]
+image::./img/browser-back.png[]
NOTE: For more details about page storing you can take a look at paragraph "Page storing" from chapter "Wicket Internals" The content of this paragraph is from wiki page https://cwiki.apache.org/confluence/display/WICKET/Page+Storage.
@@ -96,7 +96,7 @@ NOTE: Scoped variables will be introduced in <<requestProcessing.adoc#_storing_a
The following picture is an overview of these two caching levels:
-image::../img/wicket-cache.png[]
+image::./img/wicket-cache.png[]
Wicket allows us to set the maximum size of the file used to store pages with setting class _org.apache.wicket.settings.StoreSettings_.
This class provides the _setMaxSizePerSession(Bytes bytes)_ method to set the size of the file. The Bytes parameter is the maximum size allowed for this file:
@@ -113,13 +113,13 @@ public void init()
Class _org.apache.wicket.util.lang.Bytes_ is an utility class provided by Wicket to express size in bytes (for further details refer to the JavaDoc).
-NOTE: More insights on internal page storing will be covered in <<internals.adoc#_wicket_internals,chapter 26>>
+NOTE: More insights on internal page storing will be covered in <<internals.adoc#_wicket_internals,chapter 26>>
=== Page expiration
Page instances are not kept in the user session forever. They can be discarded when the limit set with the _setMaxSizePerSession_ method is reached or (more often) when user session expires. When we ask Wicket for a page id corresponding to a page instance removed from the session, we bump into a _PageExpiredException_ and we get the following default error page:
-image::../img/page-expired.png[]
+image::./img/page-expired.png[]
This error page can be customized with the _setPageExpiredErrorPage_ method of class _org.apache.wicket.settings.ApplicationSettings_:
diff --git a/wicket-user-guide/src/main/asciidoc/whyLearn/whyLearn_2.adoc b/wicket-user-guide/src/main/asciidoc/whyLearn/whyLearn_2.adoc
index b1a95f6410..658ac6b2df 100644
--- a/wicket-user-guide/src/main/asciidoc/whyLearn/whyLearn_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/whyLearn/whyLearn_2.adoc
@@ -5,7 +5,7 @@ Component oriented frameworks differ from classic web frameworks in that they bu
2. it is built before HTML is sent to the client
3. HTML code is generated using this model and not vice versa.
-image::../img/requesthandling-general.png[]
+image::./img/requesthandling-general.png[]
_General schema of page request handling for a component oriented framework_
diff --git a/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_2.adoc b/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_2.adoc
index eef717ce5f..1b2efa4480 100644
--- a/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_2.adoc
+++ b/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_2.adoc
@@ -3,7 +3,7 @@
Module tinymce offers integration with the namesake JavaScript library that turns our “humble” text-areas into a full-featured HTML WYSIWYG editor:
-image::../img/tinymce.png[]
+image::./img/tinymce.png[]
To “tinyfy” a textarea component we must use behavior TinyMceBehavior:
@@ -15,7 +15,7 @@ textArea.add(new TinyMceBehavior());
By default TinyMceBehavior adds only a basic set of functionalities to our textarea:
-image::../img/tinymce_basic.png[]
+image::./img/tinymce_basic.png[]
To add more functionalities we must use class TinyMCESettings to register additional TinyMCE plugins and to customize the toolbars buttons. The following code is an excerpt from example page FullFeaturedTinyMCEPage:
diff --git a/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_4.adoc b/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_4.adoc
index 9ac116f394..a44236630e 100644
--- a/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_4.adoc
+++ b/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_4.adoc
@@ -10,7 +10,7 @@ To integrate the https://developers.google.com/chart/[Google Chart] tool into o
...
<h2>Hello World</h2>
<img wicket:id="helloWorld"/>
-...
+...
----
*Java code:*
@@ -30,6 +30,6 @@ add(new Chart("helloWorld", provider));
*Displayed chart:*
-image::../img/googlechart.png[]
+image::./img/googlechart.png[]
-As we can see in the snippet above, component Chart must be used with <img> tag while the input data returned by IChartData must be a two-dimensional array of double values.
+As we can see in the snippet above, component Chart must be used with <img> tag while the input data returned by IChartData must be a two-dimensional array of double values.
diff --git a/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_5.adoc b/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_5.adoc
index 37d889ff45..1b21bcb215 100644
--- a/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_5.adoc
+++ b/wicket-user-guide/src/main/asciidoc/wicketstuff/wicketstuff_5.adoc
@@ -1,17 +1,17 @@
-Module wicketstuff-inmethod-grid implements a sophisticated grid-component with class com. inmethod.grid.datagrid.DataGrid.
+Module wicketstuff-inmethod-grid implements a sophisticated grid-component with class com. inmethod.grid.datagrid.DataGrid.
Just like pageable repeaters (seen in <<repeaters.adoc#_pageable_repeaters,paragraph 13.4>>) DataGrid provides data pagination and uses interface IDataProvider as data source. In addition the component is completely ajaxified:
-image::../img/inmethod-grid1.png[]
+image::./img/inmethod-grid1.png[]
DataGrid supports also editable cells and row selection:
-image::../img/inmethod-grid2.png[]
+image::./img/inmethod-grid2.png[]
-The following snippet illustrate how to use DataGrid and is taken from wiki page https://github.com/wicketstuff/core/wiki/InMethodGrid[https://github.com/wicketstuff/core/wiki/InMethodGrid] :
+The following snippet illustrate how to use DataGrid and is taken from wiki page https://github.com/wicketstuff/core/wiki/InMethodGrid[https://github.com/wicketstuff/core/wiki/InMethodGrid] :
*HTML:*
@@ -19,7 +19,7 @@ The following snippet illustrate how to use DataGrid and is taken from wiki page
----
...
<div wicket:id="grid">Grid</div>
-...
+...
----
*Java code:*