Archive for the ‘Wicket’ Category
Specific Examples of Components
Now I’ll give you some cheat examples for using components.
And also a little example with AJAX.
A note which applies to every featured component here:
In some situations, it could be handy that you declare the field of the component-object as a member field.
How to make a Link:
//Within a constructor or function in a Class inherited from BasePage: this.add( new Link<Void>( "exampleLink" ) { @Override public void onClick() { // Code goes here } } );
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p><a href="#" wicket:id="exampleLink">click here</a></p> </wicket:extend> </body> </html>
How to make a BookmarkablePageLink:
The difference is that this type of link could be bookmarked, the other type, Link, not.
//Within a constructor or function in a Class inherited from BasePage: this.add( new BookmarkablePageLink<Void>( "exampleBookLink", NextPage.class );
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p><a href="#" wicket:id="exampleBookLink">click here</a></p> </wicket:extend> </body> </html>
How to make a Label:
A label is used to replace static information with information from the logic layer.
/// Class definition inherited from BasePage private String personName; /** * Constructor: */ public ExamplePage() { this.personName = "John Doe"; this.add( new Label("lblPersonName", new PropertyModel<String>(this, "personName") ); }
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>Welcome <span wicket:id="lblPersonName">Nobody</span> !</p> </wicket:extend> </body> </html>
How to make a Form:
public class ExamplePage extends BasePage { /** * Constructor: */ public ExamplePage() { super(); // Note: In some situations, it could be handy that you declare the field of your Form as member field. Form exampleForm = new Form("exampleForm") { @Override public void onSubmit() { // More code goes here } }; this.add(exampleForm); } }
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>This an example page</p> <form wicket:id="exampleForm"> <label>This is an example of the form</label> <!-- More code goes here --> </form> </wicket:extend> </body> </html>
Some form-specific components:
How to make a Button:
Button-Objects are more used to create a submit button for the form, which each their own destination.
public class ExamplePage extends BasePage { /** * Constructor: */ public ExamplePage() { super(); // Note: Likely in this situation, it could be handy that you declare the field of your Form as member field. Form exampleForm = new Form("exampleForm"); exampleForm.add(new Button("btnRefresh") { @Override public void onSubmit() { super.onSubmit(); refreshScreen(); } }); this.add(exampleForm); } }
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>This an example page</p> <form wicket:id="exampleForm"> <label>This is an example of the form</label> <input wicket:id="btnRefresh" type="submit" value="Refresh" /> </form> </wicket:extend> </body> </html>
How to make a TextField:
public class ExamplePage extends BasePage { private String personName; /** * Constructor: */ public ExamplePage() { super(); this.personName = "John Doe"; // Note: Likely in this situation, it could be handy that you declare the field of your Form as member field. Form exampleForm = new Form("exampleForm"); // Please note that there are also other type of validators available: exampleForm.add(TextField<String>( "txtPersonName", , new PropertyModel<String>(this, "personName") ).add( StringValidator.minimumLength( 2 ) ).setRequired( true ); exampleForm.add(new Button("btnSave") { @Override public void onSubmit() { super.onSubmit(); save(); } }); this.add(exampleForm); } }
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>This an example page</p> <form wicket:id="exampleForm"> <label>This is an example of the form</label> <input wicket:id="txtPersonName" type="text" /> <input wicket:id="btnSave" type="submit" value="Save" /> </form> </wicket:extend> </body> </html>
How to make a TextArea:
public class ExamplePage extends BasePage { private String personDescription; /** * Constructor: */ public ExamplePage() { super(); this.personDescription= "He Loves to code"; // Note: Likely in this situation, it could be handy that you declare the field of your Form as member field. Form exampleForm = new Form("exampleForm"); // Please note that there are also other type of validators available: exampleForm.add(TextArea<String>( "txtPersonDescription", , new PropertyModel<String>(this, "personDescription") ).add( StringValidator.minimumLength( 2 ) ).setRequired( true ); exampleForm.add(new Button("btnSave") { @Override public void onSubmit() { super.onSubmit(); save(); } }); this.add(exampleForm); } }
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>This an example page</p> <form wicket:id="exampleForm"> <label>This is an example of the form</label> <input wicket:id="txtPersonDescription" type="text" /> <input wicket:id="btnSave" type="submit" value="Save" /> </form> </wicket:extend> </body> </html>
How to make a drop down chooser:
This one is somewhat complicated, since you also have to create a special class to render each option.
public class ExamplePage extends BasePage { private Status personStatus; private List<Status> states; /** * Constructor: */ public ExamplePage() { super(); // Status is an enum. this.personStatus = Status.OK; this.states = Arrays.asList(Status.values()); // Note: Likely in this situation, it could be handy that you declare the field of your Form as member field. Form exampleForm = new Form("exampleForm"); DropDownChoice chsStatus = new DropDownChoice("chsStatus", new PropertyModel<String>(this, "personStatus"), this.states, new StatusChoiceRenderer()); chsStatus.setNullValid(false); exampleForm.add(chsStatus); exampleForm.add(new Button("btnSave") { @Override public void onSubmit() { super.onSubmit(); save(); } }); this.add(exampleForm); } } /** * The choice render class for the statuses. */ private class StatusChoiceRenderer extends ChoiceRenderer<Status> { /** * Constructor: */ public StatusChoiceRenderer() { super(); } /** * @return The display value of the status * @param status The Status */ @Override public Object getDisplayValue(Status status) { return status.getStatus(); } }
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>This an example page</p> <form wicket:id="exampleForm"> <label>This is an example of the form</label> <select wicket:id="chsStatus" > <option selected="selected">Choose a status</option> <option>OK</option> <option>Standby</option> </select> <input wicket:id="btnSave" type="submit" value="Save" /> </form> </wicket:extend> </body> </html>
How to use repeating for filling a Table and Fieldsets of a Form:
public class ExamplePage extends BasePage { /** * Constructor: */ public ExamplePage() { super(); // Note: In some situations, it could be handy that you declare the field of your Form as member field. Form exampleForm = new Form("exampleForm") { List persons = personManager.getAll(); add( new ListView<Person>( "personList", persons ) { @Override protected void populateItem( ListItem<Person> li ) { final Person person = li.getModelObject(); li.add( new Label( "personId", "" + person.getID() ) ); li.add( new Label( "personName", person.getFirstName() + " " + person.getSurName() ) ); li.add( new Label( "personAddress", person.getAddress() ) ); li.add( new Label( "personTelephone", person.getTelephone() ) ); li.add( new Link<Person>( "btnDeletePerson", li.getModel() ) { @Override public void onClick() { personManager.remove( getModelObject() ); this.removePerson( getModelObject() ); } }); } }); add( new Link<Void>( "btnNewPerson" ) { @Override public void onClick() { this.addPerson(); } }); }; this.add(exampleForm); } }
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>This an example page</p> <form wicket:id="frmList"> <wicket:enclosure child=""> <table> <tr> <th>#</th> <th>Name</th> <th>Address</th> <th>Telephone</th> <th>Actions</th> </tr> <tr wicket:id="personEntry"> <td><span wicket:id="personId">0</span></td> <td><span wicket:id="personName">Name</span></td> <td><span wicket:id="personAddress">Address</span></td> <td><span wicket:id="personTelephone">Telephone</span></td> <td> <input wicket:id="btnDeletePerson" type="submit" value="Delete" /> </td> </tr> <tr> <td colspan="2"><input wicket:id="btnNewPerson" type="submit" value="New Person" /></td> </tr> </table> </wicket:enclosure> </form> </wicket:extend> </body> </html>
How to hide and unhide a component with AJAX:
public class ExamplePage extends BasePage { private WebMarkupContainer callContainer; private Status personStatus; private List<Status> states; /** * Constructor: */ public ExamplePage() { super(); // Status is an enum. this.personStatus = Status.OK; this.states = Arrays.asList(Status.values()); // Note: Likely in this situation, it could be handy that you declare the field of your Form as member field. Form exampleForm = new Form("exampleForm"); DropDownChoice chsStatus = new DropDownChoice("chsStatus", new PropertyModel<String>(this, "personStatus"), this.states, new StatusChoiceRenderer()); chsStatus.setNullValid(false); chsStatus.add(new AjaxFormComponentUpdatingBehavior("onChange") { @Override protected void onUpdate(AjaxRequestTarget target) { if (personStatus!= null) { if( (personStatus.getId() <= 1) || personStatus.getTitle().toLowerCase(). matches(".+(Standby).+") ) { amountOfKilometersContainer.setVisibilityAllowed(false); } else { callContainer.setVisibilityAllowed(true); } target.add(callContainer); } } }); exampleForm.add(chsStatus); this.callContainer = new WebMarkupContainer("callContainer"); this.callContainer.setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true); this.callContainer.setVisibilityAllowed(true); exampleForm.add(this.callContainer); this.callContainer.add(new Button("btnCall") { @Override public void onSubmit() { super.onSubmit(); call(); } }); this.add(exampleForm); } } /** * The choice render class for the statuses. */ private class StatusChoiceRenderer extends ChoiceRenderer<Status> { /** * Constructor: */ public StatusChoiceRenderer() { super(); } /** * @return The display value of the status * @param status The Status */ @Override public Object getDisplayValue(Status status) { return status.getStatus(); } }
<!DOCTYPE html> <html> <head> <title>Example Page - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>This an example page</p> <form wicket:id="exampleForm"> <label>This is an example of the form</label> <fieldset> <select wicket:id="chsStatus" > <option selected="selected">Choose a status</option> <option>OK</option> <option>Standby</option> </select> </fieldset> <fieldset wicket:id="callContainer"> <input wicket:id="btnCall" type="submit" value="Call" /> </fieldset> </form> </wicket:extend> </body> </html>
I want a main page in Apache Wicket
So, We’ve set up the database and domain, now it’s time for the GUI. With Wicket.
Of course we’ve to start the initialisation Class for our application:
package com.rivaso.exp.web; import org.apache.wicket.Page; import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession; import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication; import org.apache.wicket.markup.html.WebPage; import org.wicketstuff.javaee.injection.JavaEEComponentInjector; import com.rivaso.exp.web.secure.SignInPage; import com.rivaso.exp.web.secure.EXPAuthenticatedWebSession; import com.rivaso.exp.web.tests.TestOverviewPage; /** * @author RiVaSo * @version 1.0 */ public class Main extends AuthenticatedWebApplication { public Main() { } @Override protected void init() { super.init(); super.getComponentInstantiationListeners().add(new JavaEEComponentInjector(this)); getDebugSettings().setDevelopmentUtilitiesEnabled(true); } @Override public Class<? extends Page> getHomePage() { return MainPage.class; } @Override protected Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass() { return EXPAuthenticatedWebSession.class; } @Override protected Class<? extends WebPage> getSignInPageClass() { return SignInPage.class; } }
Then we create the class for the SignInPage:
package com.rivaso.exp.web.secure; import org.apache.wicket.request.mapper.parameter.PageParameters; import com.rivaso.exp.web.BasePage; /** * @author RiVaSo * @version 1.0 */ public class SignInPage extends BasePage { private static final long serialVersionUID = 97; public SignInPage() { this(null); } /** * Constructor: * * @param parameters The page parameters */ public SignInPage(final PageParameters parameters) { add(new JEESignInPanel("signInPanel")); } }
As you could see, we’ve to create the J2EE Sign In Panel:
package com.rivaso.exp.web.secure; import org.apache.wicket.authroles.authentication.panel.SignInPanel; /** * @author RiVaSo * @version 1.0 */ public class JEESignInPanel extends SignInPanel { private static final long serialVersionUID = 96L; public JEESignInPanel(String id) { super(id); } public JEESignInPanel(String id, boolean rememberMe) { super(id, rememberMe); } @Override protected void onBeforeRender() { EXPAuthenticatedWebSession.getExpAuthenticatedWebSession().checkJEEAuthentication(); super.onBeforeRender(); } }
And here we have the HTML-side of the SignInPage:
<!DOCTYPE html> <html> <head> <title>Please Sign In</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <span wicket:id="signInPanel"/> </wicket:extend> </body> </html>
Of course, also a NotAuthenthicatedPage and SignOutPage should be created:
package com.rivaso.exp.web.secure; import com.rivaso.exp.web.BasePage; public class NotAuthenthicatedPage extends BasePage { private static final long serialVersionUID = 0L; }
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Not Authenthicated or Authorized</title> </head> <body> <wicket:extend> <h2>Forbidden</h2> <p>You're not authorized or authenthicated for using this application.</p> <br /> <p>Please contact the administrators for requesting access.</p> </wicket:extend> </body> </html>
package com.rivaso.exp.web.secure; import com.rivaso.exp.web.BasePage; import com.rivaso.exp.web.UserPage; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.request.mapper.parameter.PageParameters; /** * @author RiVaSo * @version 1.0 */ public class SignOutPage extends BasePage { /** * Constructor: * @param parameters Page parameters */ public SignOutPage( final PageParameters parameters ) { getSession().invalidate(); add( new BookmarkablePageLink( "linkContinue", UserPage.class ) ); } }
<!DOCTYPE html> <html> <head> <title>You're logged out now</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <p>You're logged out now. Goodbye</p> <wicket:link><a href="#" wicket:id="linkContinue">Continue</a></wicket:link> </wicket:extend> </body> </html>
And now we’ve to Create a special class to initailze a session:
package com.rivaso.exp.web.secure; import java.security.Principal; import javax.ejb.EJB; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import org.apache.wicket.RestartResponseException; import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; import org.apache.wicket.authroles.authorization.strategies.role.Roles; import org.apache.wicket.injection.Injector; import org.apache.wicket.request.Request; import org.apache.wicket.request.cycle.RequestCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.rivaso.exp.domain.Person; import com.rivaso.exp.domain.Position; import com.rivaso.exp.manager.PersonManager; import com.rivaso.exp.web.Main; import com.rivaso.exp.web.SetupPage; /** * @author RiVaSo * @version 1.0 */ public class ExpAuthenticatedWebSession extends AuthenticatedWebSession { private static final long serialVersionUID = 996L; @EJB (name = "PersonManager") private PersonManager personManager; private Person authenticated; private transient Logger log = LoggerFactory.getLogger(EXPAuthenticatedWebSession.class); public EXPAuthenticatedWebSession(Request request) { super(request); Injector.get().inject(this); } public static EXPAuthenticatedWebSession getEXPAuthenticatedWebSession() { return (EXPAuthenticatedWebSession) get(); } @Override public boolean authenticate(String emailAddress, String password) { emailAddress = emailAddress.toLowerCase(); // Login using JEE security HttpServletRequest servletRequest = (HttpServletRequest) RequestCycle.get().getRequest(). getContainerRequest(); try { servletRequest.login(emailAddress, password); signIn(true); matchGlobalWithLocalUser(emailAddress); } catch (ServletException e) { // If login fails we come here return false; } return true; } private void matchGlobalWithLocalUser(String emailAddress) { try { Person personFound = personManager.getPersonByEmail(emailAddress); if (personFound != null && (personFound.isInPostion(Position.USER) || personFound. isInPostion(Position.ADMIN))) { authenticated = personFound; } } catch (Exception ex) { log.error("Error by getting person", ex); } if (this.authenticated == null) { if (personManager.count() == 0 ) { // Go to setup page. First time use. throw new RestartResponseException(SetupPage.class); } else { throw new RestartResponseException(NotAuthenthicatedPage.class); } } else { throw new RestartResponseException(NotAuthenthicatedPage.class); } } @Override public Roles getRoles() { if (isSignedIn()) { return new Roles(authenticated.getRoles()); } return null; } public Person getAuthenticated() { return this.authenticated; } /** * Checks if user is already logged in with JEE security and signs the user in if so. * Restart the response if no user is found. * * No visible modifier. Only class from this package may call this method. */ void checkJEEAuthentication() { HttpServletRequest servletRequest = (HttpServletRequest) RequestCycle.get().getRequest(). getContainerRequest(); Principal userPrincipal = servletRequest.getUserPrincipal(); if (userPrincipal != null && userPrincipal.getName() != null) { signIn(true); matchGlobalWithLocalUser(userPrincipal.getName()); } } }
And now we make the class for BasePage, which will be inherited by all our pages.
package com.rivaso.exp.web; import org.apache.wicket.Component; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.list.AbstractItem; import org.apache.wicket.model.PropertyModel; import com.rivaso.exp.domain.Person; import com.rivaso.exp.domain.Position; import com.rivaso.exp.web.secure.SignOutPage; import com.rivaso.exp.web.secure.EXPAuthenticatedWebSession; /** * @author RiVaSo * @version 1.0 */ public class BasePage extends WebPage { private static final long serialVersionUID = -166L; public BasePage() { super(); final EXPAuthenticatedWebSession expAWS = EXPAuthenticatedWebSession.getExpAuthenticatedWebSession(); add(createMenuLI(new AbstractItem("userLI")).add(new BookmarkablePageLink<Void>("user", UserPage.class))); add(createMenuLI(new AbstractItem("experienceLI")).add(new BookmarkablePageLink<Void>("experience", ExperiencePage.class))); add(createMenuLI(new AbstractItem("adminLI")).add(new BookmarkablePageLink<Void>("admin", AdminPage.class) { private static final long serialVersionUID = 1L; protected void onConfigure() { if (expAWS.isSignedIn() && expAWS.getAuthenticated() != null && expAWS.getAuthenticated().isInPostion(Position.ADMIN)) { setVisibilityAllowed(true); } else { setVisibilityAllowed(false); } }; })); add(createMenuLI(new AbstractItem("logoutLI")).add(new BookmarkablePageLink<Void>("logout", SignOutPage.class) { private static final long serialVersionUID = 1L; protected void onConfigure() { if (expAWS.isSignedIn()) { setVisibilityAllowed(true); } else { setVisibilityAllowed(false); } }; })); add(new Label("loggedin", new PropertyModel<Person>(this, "session.authenticated.emailAddress"))); } private AbstractItem createMenuLI(AbstractItem li) { li.add(new LinkActiveModifier()); return li; } class LinkActiveModifier extends AttributeAppender { public LinkActiveModifier() { super("class", "active"); super.setSeparator(" "); } private static final long serialVersionUID = 1L; @SuppressWarnings("rawtypes") @Override public boolean isEnabled(Component component) { if (component instanceof AbstractItem) { AbstractItem li = (AbstractItem) component; Component component2 = li.get(0); if (component2 instanceof BookmarkablePageLink) { BookmarkablePageLink bpl = (BookmarkablePageLink) component2; if (bpl.linksTo(BasePage.this.getPage())) { return true; } } } return false; } } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>The Experience System</title> <meta name="description" content=""/> <meta name="keywords" content=""/> <link rel="icon" type="image/png" href=""> <link rel="stylesheet" href="css/style.css" type="text/css" media="screen" /> </head> <body id="home"> <div id="page"> <div id="header"> <a href="/en/"> <img src="css/img/logo.jpg" id="logo" alt="logo"/> </a> <ul id="main_nav"> <li wicket:id="userLI" class="first "> <a href="#" wicket:id="user">User</a> </li> <li wicket:id="experienceLI" class=""> <a href="#" wicket:id="experience">Experience</a> </li> <li wicket:id="adminLI" class=""> <a href="#" wicket:id="admin">Admin</a> </li> <li wicket:id="logoutLI" class=""> <a href="#" wicket:id="logout">Logout</a> </li> </ul> </div> <div id="content_bg"> <div class="seperator"> </div> </div> <div id="content"> <wicket:child /> </div> <div class="clear"></div> <div id="footer-push"></div> </div> <div id="footer-wrap"> <div id="footer"> <ul class="left">© RiVaSo 2012</ul> <ul> <li><span wicket:id="loggedin"></span></li> </ul> </div> </div> </body> </html>
Now it’s time to make a main page, I’ve chosen to use the profile page of the user for that:
package com.rivaso.exp.web; import com.rivaso.exp.domain.Person; import com.rivaso.exp.domain.Position; import com.rivaso.exp.web.secure.NotAuthenthicatedPage; import com.rivaso.exp.web.secure.EXPAuthenticatedWebSession; import javax.naming.AuthenticationException; import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation; import org.apache.wicket.markup.html.basic.Label; /** * * @author RiVaSo * @version 1.0 */ @AuthorizeInstantiation ({Position.ADMIN_STRING, Position.USER_STRING}) public class MainPage extends BasePage { private static final long serialVersionUID = 2446731116379770530L; public MainPage() { super(); try { EXPAuthenticatedWebSession aws = (EXPAuthenticatedWebSession) this.getSession(); if (aws.isSignedIn()) { showMainPage(); } else { throw new AuthenticationException("Not signed in."); } } catch (AuthenticationException ex) { // Not signed in. ex.printStackTrace(); this.redirectToInterceptPage(new NotAuthenthicatedPage()); } } private void showMainPage() { EXPAuthenticatedWebSession aws = (EXPAuthenticatedWebSession) this.getSession(); Person person = aws.getAuthenticated(); String skills = ""; String skillsDone = ""; if (person != null) { skills = person.getTotalAmountOfSkills() + ""; skillsLeft = person.getAmountOfSkillsLeft() + ""; } add(new Label("lblFirstName", person.getFirstName())); add(new Label("lblSurName", person.getSurName())); add(new Label("lblEmailAddress", person.getEmailAddress())); add(new Label("lblAmountOfSkillsLeft", skillsLeft)); add(new Label("lblAmountOfSkills", skills)); } }
<!DOCTYPE html> <html> <head> <title>UserPage - Experience System</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <wicket:extend> <h2>Welcome <span wicket:id="lblFirstName">Pleased</span> <span wicket:id="lblSurName">User</span></h2> <p>Your email-address is: <span wicket:id="lblEmailAddress">person@riva.so</span></p> <wicket:enclosure child=""> <p>You have <span wicket:id="lblAmountOfSkillsLeft">a few</span> of the <span wicket:id="lblAmountOfSkills">big amount</span> skills left.</p> </wicket:enclosure> </wicket:extend> </body> </html>
As you could see… the tag <wicket:id> is used to insert information from the ‘logical layer’ (the Class) into your html.
The <wicket:child>-tag in the BasePage is to clarify that Wicket should put the content in the <wicket:extend>-tags of the html-versions of the childs classes inherited from BasePage.
The <wicket:enclosure>-tags are used to specify that if the content is null of a <wicket:child>-tag placed within the <wicket:enclosure>-tags, the content won’t be shown.
The attribute “child” is used to target a specific wicket:id. If you want to deactivate a specific nested wicket:id, use the attribute like this way: <wicket:enclosure child=”[parent-wicket:id]:[target-wicket:id]”>
Now, the next step it’s more on you. I’ll only give some examples for creating GUI components.