SlideShare a Scribd company logo
Part 2

Daan van Etten
    November 12, 2010
Wicket KT part 2
Testing
Models
Break
Old to new
CSS (shiny stuff)
Cool stuff
Wicket KT part 2
Testing
Base test classes


  WicketBaseTest
         for components that do not use @SpringBean



  WicketBeanTest
         for components using @SpringBean
         registerBean(String beanName, Object bean)




  WicketBasePageTest
         only for pages extending from BasePage!
Test your Panel / Page instantiation.


(this checks if HTML / Java matches)
To be discussed:

How much testing?
    or: when does a unit test
   become an integration test?
Tips



       Wicket tests are for unit testing,
         not for integration testing



        Keep your components small
        and simple, easy to unit test.
Use TestPanelSource on non standard constructors


     Constructor: ChangePasswordBlock(String id)
 	   	   m_wicketTester.startPanel(ChangePasswordBlock.class);




     Constructor: ComplexPanel(String id, T param1, T param2)
 	   	   m_wicketTester.startPanel(new TestPanelSource() {
 	   	   	   private static final long serialVersionUID = -4222357976177912509L;

 	   	   	     @Override
 	   	   	     public Panel getTestPanel(String panelId) {
 	   	   	     	   return new ComplexPanel(panelId, parameter1, parameter2);
 	   	   	     }
 	   	   });
Use FormTester to test Forms




	   	   FormTester tester = m_wicketTester.newFormTester("formid");
	   	   tester.setValue("currentPassword", "currentPassword");
	   	   tester.setValue("newPassword", "newPassword");
	   	   tester.setValue("confirmNewPassword", "newPassword");
	   	   tester.submit();
DEMO
page 322


“Testing your
   Wicket
 application”
Models
Wicket models allow components to
     retrieve and store data.
             Component

        Markup           Model
Almost every component
          accepts a model

	   public   Panel(final String id, final IModel<?> model)
	   public   Label(final String id, IModel<?> model)
	   public   TextField(final String id, final IModel<T> model)
	   public   Button(final String id, final IModel<String> model)
Dynamic
   vs

 Static
Model
+   Simple


-   not dynamically updated
    (unless overridden)
IModel streetModel = Model.of(
            student.getAddress().getStreet()

            new Label(“street”, streetModel);
IModel streetModel = Model.of(
            student.getAddress().getStreet()

            new Label(“street”, streetModel);

 Problems
IModel streetModel = Model.of(
            student.getAddress().getStreet()

              new Label(“street”, streetModel);

 Problems
    Label is not notified of street / address / student changes
IModel streetModel = Model.of(
            student.getAddress().getStreet()

              new Label(“street”, streetModel);

 Problems
    Label is not notified of street / address / student changes

    NullPointerException: student or address could be null.
PropertyModel

+   null safe
    dynamically updated

-   not rename safe
Content of models are
        stored in the Session.

Translated
    1. Model objects need to be serializable

    2. Huge objects are slow to (de)serialize
LoadableDetachable
    Only the unique identifier is in
+   the Session (small Session)


-   Every request the object is
    reloaded (can be slow)
Example:
UserLoadableDetachableModel
Example:
       UserLoadableDetachableModel

	   private final UserService m_userService;

	   /**
	     * @param userService the {@link UserService} to use for retrieving {@link User} objects.
	     */
	   public UserLoadableDetachableModel(UserService userService) {
	   	     this(userService, null);
	   }
Example:
       UserLoadableDetachableModel

	   private final UserService m_userService;

	   /**
	     * @param userService the {@link UserService} to use for retrieving {@link User} objects.
	     */
	   public UserLoadableDetachableModel(UserService userService) {
	   	     this(userService, null);
	   }




The Service is a constructor argument.
Example:
       UserLoadableDetachableModel

	   private final UserService m_userService;

	   /**
	     * @param userService the {@link UserService} to use for retrieving {@link User} objects.
	     */
	   public UserLoadableDetachableModel(UserService userService) {
	   	     this(userService, null);
	   }




The Service is a constructor argument.

Use a SpringBeaned service for that, so
serializing works.
Example:
UserLoadableDetachableModel

 	   @Override
 	   protected User load() {
 	   	   if (m_userId != null) {
 	   	   	   return m_userService.getObject(m_userId);
 	   	   } else {
 	   	   	   return null;
 	   	   }
 	   }

 	   @Override
 	   public void setObject(User user) {
 	   	   super.setObject(user);

 	   	   m_userId = null;
 	   	   if (user != null){
 	   	   	   m_userId = user.getId();
 	   	   }
 	   }
Almost every component
          accepts a model

	   public   Panel(final String id, final IModel<?> model)
	   public   Label(final String id, IModel<?> model)
	   public   TextField(final String id, final IModel<T> model)
	   public   Button(final String id, final IModel<String> model)



                models attached to Wicket
               components automatically get
                 detached and reattached!
https://cwiki.apache.org/WICKET/
working-with-wicket-models.html
CSS (shiny stuff)
New!   ‘CSS component’
Example

	   public Toolbar(String id, IModel itemsModel) {
	   	 super(id);
	   	 m_itemsModel = itemsModel;
	   	 add(new PropertyListView("menuitemholder", itemsModel) {
	   	 	 	 @Override
	   	 	 	 protected void populateItem(ListItem listItem) {
	   	 	 	 	 MenuItem menuItem = (MenuItem) listItem.getModelObject();
	   	 	 	 	 listItem.add(new ToolbarItem("menuitem", menuItem));
	   	 	 	 	 listItem.setRenderBodyOnly(true);
	   	 	 	 }
	   	 	 }.setOutputMarkupId(true));
Problems?


	   public Toolbar(String id, IModel itemsModel) {
	   	 super(id);
	   	 m_itemsModel = itemsModel;
	   	 add(new PropertyListView("menuitemholder", itemsModel) {
	   	 	 	 @Override
	   	 	 	 protected void populateItem(ListItem listItem) {
	   	 	 	 	 MenuItem menuItem = (MenuItem) listItem.getModelObject();
	   	 	 	 	 listItem.add(new ToolbarItem("menuitem", menuItem));
	   	 	 	 	 listItem.setRenderBodyOnly(true);
	   	 	 	 }
	   	 	 }.setOutputMarkupId(true));
Problems?
    What if:




	   public Toolbar(String id, IModel itemsModel) {
	   	 super(id);
	   	 m_itemsModel = itemsModel;
	   	 add(new PropertyListView("menuitemholder", itemsModel) {
	   	 	 	 @Override
	   	 	 	 protected void populateItem(ListItem listItem) {
	   	 	 	 	 MenuItem menuItem = (MenuItem) listItem.getModelObject();
	   	 	 	 	 listItem.add(new ToolbarItem("menuitem", menuItem));
	   	 	 	 	 listItem.setRenderBodyOnly(true);
	   	 	 	 }
	   	 	 }.setOutputMarkupId(true));
Problems?
    What if:       you want to add a Wicket AjaxButton?




	   public Toolbar(String id, IModel itemsModel) {
	   	 super(id);
	   	 m_itemsModel = itemsModel;
	   	 add(new PropertyListView("menuitemholder", itemsModel) {
	   	 	 	 @Override
	   	 	 	 protected void populateItem(ListItem listItem) {
	   	 	 	 	 MenuItem menuItem = (MenuItem) listItem.getModelObject();
	   	 	 	 	 listItem.add(new ToolbarItem("menuitem", menuItem));
	   	 	 	 	 listItem.setRenderBodyOnly(true);
	   	 	 	 }
	   	 	 }.setOutputMarkupId(true));
Problems?
    What if:       you want to add a Wicket AjaxButton?
                   you have to override ToolbarItem (onClick is there)?



	   public Toolbar(String id, IModel itemsModel) {
	   	 super(id);
	   	 m_itemsModel = itemsModel;
	   	 add(new PropertyListView("menuitemholder", itemsModel) {
	   	 	 	 @Override
	   	 	 	 protected void populateItem(ListItem listItem) {
	   	 	 	 	 MenuItem menuItem = (MenuItem) listItem.getModelObject();
	   	 	 	 	 listItem.add(new ToolbarItem("menuitem", menuItem));
	   	 	 	 	 listItem.setRenderBodyOnly(true);
	   	 	 	 }
	   	 	 }.setOutputMarkupId(true));
Problems?
    What if:       you want to add a Wicket AjaxButton?
                   you have to override ToolbarItem (onClick is there)?
                   you want to put in a different dropdown structure?


	   public Toolbar(String id, IModel itemsModel) {
	   	 super(id);
	   	 m_itemsModel = itemsModel;
	   	 add(new PropertyListView("menuitemholder", itemsModel) {
	   	 	 	 @Override
	   	 	 	 protected void populateItem(ListItem listItem) {
	   	 	 	 	 MenuItem menuItem = (MenuItem) listItem.getModelObject();
	   	 	 	 	 listItem.add(new ToolbarItem("menuitem", menuItem));
	   	 	 	 	 listItem.setRenderBodyOnly(true);
	   	 	 	 }
	   	 	 }.setOutputMarkupId(true));
More abstract look at Toolbar
More abstract look at Toolbar

• Toolbar is a blue bar on top of the page, containing ToolbarItems.
More abstract look at Toolbar

• Toolbar is a blue bar on top of the page, containing ToolbarItems.
• Toolbar gets a list of MenuItem’s.
More abstract look at Toolbar

• Toolbar is a blue bar on top of the page, containing ToolbarItems.
• Toolbar gets a list of MenuItem’s.
• For every MenuItem, a ToolbarItem is created inside Toolbar.
More abstract look at Toolbar

• Toolbar is a blue bar on top of the page, containing ToolbarItems.
• Toolbar gets a list of MenuItem’s.
• For every MenuItem, a ToolbarItem is created inside Toolbar.
• ToolbarItem is not really extendable.
More abstract look at Toolbar

• Toolbar is a blue bar on top of the page, containing ToolbarItems.
• Toolbar gets a list of MenuItem’s.
• For every MenuItem, a ToolbarItem is created inside Toolbar.
• ToolbarItem is not really extendable.
• ItemLink’s are created inside ToolbarItem.
More abstract look at Toolbar

• Toolbar is a blue bar on top of the page, containing ToolbarItems.
• Toolbar gets a list of MenuItem’s.
• For every MenuItem, a ToolbarItem is created inside Toolbar.
• ToolbarItem is not really extendable.
• ItemLink’s are created inside ToolbarItem.
• ItemLink is effectively not extendable.
More abstract look at Toolbar
Remove assumptions
 • Toolbar is a blue bar on top of the page, containing ToolbarItems.
 • Toolbar gets a list of MenuItem’s.
 • For every MenuItem, a ToolbarItem is created inside Toolbar.
 • ToolbarItem is not really extendable.
 • ItemLink’s are created inside ToolbarItem.
 • ItemLink is effectively not extendable.
More abstract look at Toolbar
Remove assumptions
 • Toolbar is a blue bar on top of the page, containing ToolbarItems.
                                                        ------------
 • Toolbar gets a list of MenuItem’s.
 • For every MenuItem, a ToolbarItem is created inside Toolbar.
 • ToolbarItem is not really extendable.
 • ItemLink’s are created inside ToolbarItem.
 • ItemLink is effectively not extendable.
More abstract look at Toolbar
Remove assumptions
• Toolbar is a blue bar on top of the page, containing ToolbarItems.
                                                       ------------
• Toolbar gets a list of MenuItem’s.
------------------------------------------------
• For every MenuItem, a ToolbarItem is created inside Toolbar.
• ToolbarItem is not really extendable.
• ItemLink’s are created inside ToolbarItem.
• ItemLink is effectively not extendable.
More abstract look at Toolbar
Remove assumptions
• Toolbar is a blue bar on top of the page, containing ToolbarItems.
                                                       ------------
• Toolbar gets a list of MenuItem’s.
------------------------------------------------
• For every MenuItem, a ToolbarItem is created inside Toolbar.
------------------------------------------------
• ToolbarItem is not really extendable.
• ItemLink’s are created inside ToolbarItem.
• ItemLink is effectively not extendable.
More abstract look at Toolbar
Remove assumptions
• Toolbar is a blue bar on top of the page, containing ToolbarItems.
                                                       ------------
• Toolbar gets a list of MenuItem’s.
------------------------------------------------
• For every MenuItem, a ToolbarItem is created inside Toolbar.
------------------------------------------------
• ToolbarItem is not really extendable.
------------------------------------------------
• ItemLink’s are created inside ToolbarItem.
• ItemLink is effectively not extendable.
More abstract look at Toolbar
Remove assumptions
• Toolbar is a blue bar on top of the page, containing ToolbarItems.
                                                       ------------
• Toolbar gets a list of MenuItem’s.
------------------------------------------------
• For every MenuItem, a ToolbarItem is created inside Toolbar.
------------------------------------------------
• ToolbarItem is not really extendable.
------------------------------------------------
• ItemLink’s are created inside ToolbarItem.
------------------------------------------------
• ItemLink is effectively not extendable.
More abstract look at Toolbar
Remove assumptions
• Toolbar is a blue bar on top of the page, containing ToolbarItems.
                                                       ------------
• Toolbar gets a list of MenuItem’s.
------------------------------------------------
• For every MenuItem, a ToolbarItem is created inside Toolbar.
------------------------------------------------
• ToolbarItem is not really extendable.
------------------------------------------------
• ItemLink’s are created inside ToolbarItem.
------------------------------------------------
• ItemLink is effectively not extendable.
------------------------------------------------
More abstract look at Toolbar
Remove assumptions
• Toolbar is a blue bar -------------- containing ToolbarItems.
                         on top of the page,         ------------
• Toolbar gets a list of MenuItem’s.
------------------------------------------------
• For every MenuItem, a ToolbarItem is created inside Toolbar.
------------------------------------------------
• ToolbarItem is not really extendable.
------------------------------------------------
• ItemLink’s are created inside ToolbarItem.
------------------------------------------------
• ItemLink is effectively not extendable.
------------------------------------------------
More abstract look at Toolbar
Remove assumptions
• Toolbar is a blue bar -------------- containing ToolbarItems.
                         on top of the page,         ------------
• Toolbar gets a list of MenuItem’s.
------------------------------------------------
• For every MenuItem, a ToolbarItem is created inside Toolbar.
------------------------------------------------
• ToolbarItem is not really extendable.
------------------------------------------------
• ItemLink’s are created inside ToolbarItem.
------------------------------------------------
• ItemLink is effectively not extendable.
------------------------------------------------



  > Toolbar is a blue bar, containing
  something
New!   ‘CSS component’

Advantages
 + Easy to get a consistent UI
 + No API, so no limitations
educatorbase.css

 /**
 	   Header component, a blue bar with dark blue text.
 	   Used to create blocks of content on the page.
 	   Use BluePrint to set the width of the div around it, by default a div is 100% wide.

 	        HTML example:
 	        <div class="blockheader">HEADER CONTENT</div>
     */
educatorbase.css

  /**
    Block of content with a margin around it.
    Used to create blocks of content on the page, for example under a div header.
    Use BluePrint to set the width of the div around it, by default a div is 100% wide.

  	        HTML example:
  	        <div class="header">HEADER CONTENT</div>
  	        <div class="block">
  	        	   BLOCK CONTENT
  	        </div>
      */
educatorbase.css

  /**
  	   Page title, large dark blue text.
  	   Used above a page to show the title of the page.
  	
  	   Important: do not use anywhere else, only at the beginning of a page.

  	        HTML example: <h1>PAGE TITLE</h1>
      */

More Related Content

PPT
PPT
JQuery New Evolution
PPTX
jQuery
PDF
Web Design & Development - Session 6
PDF
Android Testing
PDF
Effective Android Data Binding
PDF
Action Bar in Android
PDF
Modern Android Architecture
JQuery New Evolution
jQuery
Web Design & Development - Session 6
Android Testing
Effective Android Data Binding
Action Bar in Android
Modern Android Architecture

What's hot (12)

PDF
12advanced Swing
PPTX
DOCX
Kode vb.net
PDF
Annihilate test smells by refactoring to patterns
PPTX
Handling action bar in Android
PDF
jQuery1.2.cheatsheet.v1.0
PDF
PDF
qooxdoo Form Management
PDF
What the FUF?
PDF
Functional programming techniques in real-world microservices
PDF
Selectors and normalizing state shape
PDF
Михаил Анохин "Data binding 2.0"
12advanced Swing
Kode vb.net
Annihilate test smells by refactoring to patterns
Handling action bar in Android
jQuery1.2.cheatsheet.v1.0
qooxdoo Form Management
What the FUF?
Functional programming techniques in real-world microservices
Selectors and normalizing state shape
Михаил Анохин "Data binding 2.0"
Ad

Similar to Wicket KT part 2 (20)

PDF
Apache Wicket Web Framework
ODP
Wicket Next (1.4/1.5)
PDF
Wicket In Action - oredev2008
PDF
Rich Internet Applications con JavaFX e NetBeans
PDF
Apache Wicket: 10 jaar en verder - Martijn Dashorst
KEY
Integrating Wicket with Java EE 6
PPTX
Rapid prototyping of eclipse rcp applications - Eclipsecon Europe 2017
PPT
Component Framework Primer for JSF Users
ODT
Eclipse Tricks
PPT
12 global fetching strategies
ODP
Modelibra Software Family
PPTX
Sling models by Justin Edelson
PPTX
Apache Wicket
PDF
Wicket 10 years and beyond
PPT
Svcc Building Rich Applications with Groovy's SwingBuilder
ODP
Wicket and the Generics Battle (and a bit more)
PPTX
Hypermedia-driven Web Services with Spring Data REST
PDF
Java Swing Custom GUI MVC Component Tutorial
PPT
CodeMash - Building Rich Apps with Groovy SwingBuilder
PDF
Learn about Eclipse e4 from Lars Vogel at SF-JUG
Apache Wicket Web Framework
Wicket Next (1.4/1.5)
Wicket In Action - oredev2008
Rich Internet Applications con JavaFX e NetBeans
Apache Wicket: 10 jaar en verder - Martijn Dashorst
Integrating Wicket with Java EE 6
Rapid prototyping of eclipse rcp applications - Eclipsecon Europe 2017
Component Framework Primer for JSF Users
Eclipse Tricks
12 global fetching strategies
Modelibra Software Family
Sling models by Justin Edelson
Apache Wicket
Wicket 10 years and beyond
Svcc Building Rich Applications with Groovy's SwingBuilder
Wicket and the Generics Battle (and a bit more)
Hypermedia-driven Web Services with Spring Data REST
Java Swing Custom GUI MVC Component Tutorial
CodeMash - Building Rich Apps with Groovy SwingBuilder
Learn about Eclipse e4 from Lars Vogel at SF-JUG
Ad

Recently uploaded (20)

PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
Telecom Fraud Prevention Guide | Hyperlink InfoSystem
PDF
Chapter 2 Digital Image Fundamentals.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
Big Data Technologies - Introduction.pptx
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Reimagining Insurance: Connected Data for Confident Decisions.pdf
PDF
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
PPTX
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
PDF
Modernizing your data center with Dell and AMD
PDF
CIFDAQ's Market Wrap: Ethereum Leads, Bitcoin Lags, Institutions Shift
PDF
madgavkar20181017ppt McKinsey Presentation.pdf
PDF
[발표본] 너의 과제는 클라우드에 있어_KTDS_김동현_20250524.pdf
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
HCSP-Presales-Campus Network Planning and Design V1.0 Training Material-Witho...
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Smarter Business Operations Powered by IoT Remote Monitoring
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Review of recent advances in non-invasive hemoglobin estimation
Telecom Fraud Prevention Guide | Hyperlink InfoSystem
Chapter 2 Digital Image Fundamentals.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
Big Data Technologies - Introduction.pptx
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
NewMind AI Monthly Chronicles - July 2025
Reimagining Insurance: Connected Data for Confident Decisions.pdf
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Modernizing your data center with Dell and AMD
CIFDAQ's Market Wrap: Ethereum Leads, Bitcoin Lags, Institutions Shift
madgavkar20181017ppt McKinsey Presentation.pdf
[발표본] 너의 과제는 클라우드에 있어_KTDS_김동현_20250524.pdf
CIFDAQ's Market Insight: SEC Turns Pro Crypto
HCSP-Presales-Campus Network Planning and Design V1.0 Training Material-Witho...
20250228 LYD VKU AI Blended-Learning.pptx
Smarter Business Operations Powered by IoT Remote Monitoring
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication

Wicket KT part 2

  • 1. Part 2 Daan van Etten November 12, 2010
  • 11. Base test classes WicketBaseTest for components that do not use @SpringBean WicketBeanTest for components using @SpringBean registerBean(String beanName, Object bean) WicketBasePageTest only for pages extending from BasePage!
  • 12. Test your Panel / Page instantiation. (this checks if HTML / Java matches)
  • 13. To be discussed: How much testing? or: when does a unit test become an integration test?
  • 14. Tips Wicket tests are for unit testing, not for integration testing Keep your components small and simple, easy to unit test.
  • 15. Use TestPanelSource on non standard constructors Constructor: ChangePasswordBlock(String id) m_wicketTester.startPanel(ChangePasswordBlock.class); Constructor: ComplexPanel(String id, T param1, T param2) m_wicketTester.startPanel(new TestPanelSource() { private static final long serialVersionUID = -4222357976177912509L; @Override public Panel getTestPanel(String panelId) { return new ComplexPanel(panelId, parameter1, parameter2); } });
  • 16. Use FormTester to test Forms FormTester tester = m_wicketTester.newFormTester("formid"); tester.setValue("currentPassword", "currentPassword"); tester.setValue("newPassword", "newPassword"); tester.setValue("confirmNewPassword", "newPassword"); tester.submit();
  • 17. DEMO
  • 18. page 322 “Testing your Wicket application”
  • 20. Wicket models allow components to retrieve and store data. Component Markup Model
  • 21. Almost every component accepts a model public Panel(final String id, final IModel<?> model) public Label(final String id, IModel<?> model) public TextField(final String id, final IModel<T> model) public Button(final String id, final IModel<String> model)
  • 22. Dynamic vs Static
  • 23. Model + Simple - not dynamically updated (unless overridden)
  • 24. IModel streetModel = Model.of( student.getAddress().getStreet() new Label(“street”, streetModel);
  • 25. IModel streetModel = Model.of( student.getAddress().getStreet() new Label(“street”, streetModel); Problems
  • 26. IModel streetModel = Model.of( student.getAddress().getStreet() new Label(“street”, streetModel); Problems Label is not notified of street / address / student changes
  • 27. IModel streetModel = Model.of( student.getAddress().getStreet() new Label(“street”, streetModel); Problems Label is not notified of street / address / student changes NullPointerException: student or address could be null.
  • 28. PropertyModel + null safe dynamically updated - not rename safe
  • 29. Content of models are stored in the Session. Translated 1. Model objects need to be serializable 2. Huge objects are slow to (de)serialize
  • 30. LoadableDetachable Only the unique identifier is in + the Session (small Session) - Every request the object is reloaded (can be slow)
  • 32. Example: UserLoadableDetachableModel private final UserService m_userService; /** * @param userService the {@link UserService} to use for retrieving {@link User} objects. */ public UserLoadableDetachableModel(UserService userService) { this(userService, null); }
  • 33. Example: UserLoadableDetachableModel private final UserService m_userService; /** * @param userService the {@link UserService} to use for retrieving {@link User} objects. */ public UserLoadableDetachableModel(UserService userService) { this(userService, null); } The Service is a constructor argument.
  • 34. Example: UserLoadableDetachableModel private final UserService m_userService; /** * @param userService the {@link UserService} to use for retrieving {@link User} objects. */ public UserLoadableDetachableModel(UserService userService) { this(userService, null); } The Service is a constructor argument. Use a SpringBeaned service for that, so serializing works.
  • 35. Example: UserLoadableDetachableModel @Override protected User load() { if (m_userId != null) { return m_userService.getObject(m_userId); } else { return null; } } @Override public void setObject(User user) { super.setObject(user); m_userId = null; if (user != null){ m_userId = user.getId(); } }
  • 36. Almost every component accepts a model public Panel(final String id, final IModel<?> model) public Label(final String id, IModel<?> model) public TextField(final String id, final IModel<T> model) public Button(final String id, final IModel<String> model) models attached to Wicket components automatically get detached and reattached!
  • 39. New! ‘CSS component’
  • 40. Example public Toolbar(String id, IModel itemsModel) { super(id); m_itemsModel = itemsModel; add(new PropertyListView("menuitemholder", itemsModel) { @Override protected void populateItem(ListItem listItem) { MenuItem menuItem = (MenuItem) listItem.getModelObject(); listItem.add(new ToolbarItem("menuitem", menuItem)); listItem.setRenderBodyOnly(true); } }.setOutputMarkupId(true));
  • 41. Problems? public Toolbar(String id, IModel itemsModel) { super(id); m_itemsModel = itemsModel; add(new PropertyListView("menuitemholder", itemsModel) { @Override protected void populateItem(ListItem listItem) { MenuItem menuItem = (MenuItem) listItem.getModelObject(); listItem.add(new ToolbarItem("menuitem", menuItem)); listItem.setRenderBodyOnly(true); } }.setOutputMarkupId(true));
  • 42. Problems? What if: public Toolbar(String id, IModel itemsModel) { super(id); m_itemsModel = itemsModel; add(new PropertyListView("menuitemholder", itemsModel) { @Override protected void populateItem(ListItem listItem) { MenuItem menuItem = (MenuItem) listItem.getModelObject(); listItem.add(new ToolbarItem("menuitem", menuItem)); listItem.setRenderBodyOnly(true); } }.setOutputMarkupId(true));
  • 43. Problems? What if: you want to add a Wicket AjaxButton? public Toolbar(String id, IModel itemsModel) { super(id); m_itemsModel = itemsModel; add(new PropertyListView("menuitemholder", itemsModel) { @Override protected void populateItem(ListItem listItem) { MenuItem menuItem = (MenuItem) listItem.getModelObject(); listItem.add(new ToolbarItem("menuitem", menuItem)); listItem.setRenderBodyOnly(true); } }.setOutputMarkupId(true));
  • 44. Problems? What if: you want to add a Wicket AjaxButton? you have to override ToolbarItem (onClick is there)? public Toolbar(String id, IModel itemsModel) { super(id); m_itemsModel = itemsModel; add(new PropertyListView("menuitemholder", itemsModel) { @Override protected void populateItem(ListItem listItem) { MenuItem menuItem = (MenuItem) listItem.getModelObject(); listItem.add(new ToolbarItem("menuitem", menuItem)); listItem.setRenderBodyOnly(true); } }.setOutputMarkupId(true));
  • 45. Problems? What if: you want to add a Wicket AjaxButton? you have to override ToolbarItem (onClick is there)? you want to put in a different dropdown structure? public Toolbar(String id, IModel itemsModel) { super(id); m_itemsModel = itemsModel; add(new PropertyListView("menuitemholder", itemsModel) { @Override protected void populateItem(ListItem listItem) { MenuItem menuItem = (MenuItem) listItem.getModelObject(); listItem.add(new ToolbarItem("menuitem", menuItem)); listItem.setRenderBodyOnly(true); } }.setOutputMarkupId(true));
  • 46. More abstract look at Toolbar
  • 47. More abstract look at Toolbar • Toolbar is a blue bar on top of the page, containing ToolbarItems.
  • 48. More abstract look at Toolbar • Toolbar is a blue bar on top of the page, containing ToolbarItems. • Toolbar gets a list of MenuItem’s.
  • 49. More abstract look at Toolbar • Toolbar is a blue bar on top of the page, containing ToolbarItems. • Toolbar gets a list of MenuItem’s. • For every MenuItem, a ToolbarItem is created inside Toolbar.
  • 50. More abstract look at Toolbar • Toolbar is a blue bar on top of the page, containing ToolbarItems. • Toolbar gets a list of MenuItem’s. • For every MenuItem, a ToolbarItem is created inside Toolbar. • ToolbarItem is not really extendable.
  • 51. More abstract look at Toolbar • Toolbar is a blue bar on top of the page, containing ToolbarItems. • Toolbar gets a list of MenuItem’s. • For every MenuItem, a ToolbarItem is created inside Toolbar. • ToolbarItem is not really extendable. • ItemLink’s are created inside ToolbarItem.
  • 52. More abstract look at Toolbar • Toolbar is a blue bar on top of the page, containing ToolbarItems. • Toolbar gets a list of MenuItem’s. • For every MenuItem, a ToolbarItem is created inside Toolbar. • ToolbarItem is not really extendable. • ItemLink’s are created inside ToolbarItem. • ItemLink is effectively not extendable.
  • 53. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar on top of the page, containing ToolbarItems. • Toolbar gets a list of MenuItem’s. • For every MenuItem, a ToolbarItem is created inside Toolbar. • ToolbarItem is not really extendable. • ItemLink’s are created inside ToolbarItem. • ItemLink is effectively not extendable.
  • 54. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar on top of the page, containing ToolbarItems. ------------ • Toolbar gets a list of MenuItem’s. • For every MenuItem, a ToolbarItem is created inside Toolbar. • ToolbarItem is not really extendable. • ItemLink’s are created inside ToolbarItem. • ItemLink is effectively not extendable.
  • 55. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar on top of the page, containing ToolbarItems. ------------ • Toolbar gets a list of MenuItem’s. ------------------------------------------------ • For every MenuItem, a ToolbarItem is created inside Toolbar. • ToolbarItem is not really extendable. • ItemLink’s are created inside ToolbarItem. • ItemLink is effectively not extendable.
  • 56. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar on top of the page, containing ToolbarItems. ------------ • Toolbar gets a list of MenuItem’s. ------------------------------------------------ • For every MenuItem, a ToolbarItem is created inside Toolbar. ------------------------------------------------ • ToolbarItem is not really extendable. • ItemLink’s are created inside ToolbarItem. • ItemLink is effectively not extendable.
  • 57. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar on top of the page, containing ToolbarItems. ------------ • Toolbar gets a list of MenuItem’s. ------------------------------------------------ • For every MenuItem, a ToolbarItem is created inside Toolbar. ------------------------------------------------ • ToolbarItem is not really extendable. ------------------------------------------------ • ItemLink’s are created inside ToolbarItem. • ItemLink is effectively not extendable.
  • 58. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar on top of the page, containing ToolbarItems. ------------ • Toolbar gets a list of MenuItem’s. ------------------------------------------------ • For every MenuItem, a ToolbarItem is created inside Toolbar. ------------------------------------------------ • ToolbarItem is not really extendable. ------------------------------------------------ • ItemLink’s are created inside ToolbarItem. ------------------------------------------------ • ItemLink is effectively not extendable.
  • 59. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar on top of the page, containing ToolbarItems. ------------ • Toolbar gets a list of MenuItem’s. ------------------------------------------------ • For every MenuItem, a ToolbarItem is created inside Toolbar. ------------------------------------------------ • ToolbarItem is not really extendable. ------------------------------------------------ • ItemLink’s are created inside ToolbarItem. ------------------------------------------------ • ItemLink is effectively not extendable. ------------------------------------------------
  • 60. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar -------------- containing ToolbarItems. on top of the page, ------------ • Toolbar gets a list of MenuItem’s. ------------------------------------------------ • For every MenuItem, a ToolbarItem is created inside Toolbar. ------------------------------------------------ • ToolbarItem is not really extendable. ------------------------------------------------ • ItemLink’s are created inside ToolbarItem. ------------------------------------------------ • ItemLink is effectively not extendable. ------------------------------------------------
  • 61. More abstract look at Toolbar Remove assumptions • Toolbar is a blue bar -------------- containing ToolbarItems. on top of the page, ------------ • Toolbar gets a list of MenuItem’s. ------------------------------------------------ • For every MenuItem, a ToolbarItem is created inside Toolbar. ------------------------------------------------ • ToolbarItem is not really extendable. ------------------------------------------------ • ItemLink’s are created inside ToolbarItem. ------------------------------------------------ • ItemLink is effectively not extendable. ------------------------------------------------ > Toolbar is a blue bar, containing something
  • 62. New! ‘CSS component’ Advantages + Easy to get a consistent UI + No API, so no limitations
  • 63. educatorbase.css /** Header component, a blue bar with dark blue text. Used to create blocks of content on the page. Use BluePrint to set the width of the div around it, by default a div is 100% wide. HTML example: <div class="blockheader">HEADER CONTENT</div> */
  • 64. educatorbase.css /** Block of content with a margin around it. Used to create blocks of content on the page, for example under a div header. Use BluePrint to set the width of the div around it, by default a div is 100% wide. HTML example: <div class="header">HEADER CONTENT</div> <div class="block"> BLOCK CONTENT </div> */
  • 65. educatorbase.css /** Page title, large dark blue text. Used above a page to show the title of the page. Important: do not use anywhere else, only at the beginning of a page. HTML example: <h1>PAGE TITLE</h1> */