{"id":61,"date":"2011-06-06T17:43:32","date_gmt":"2011-06-07T00:43:32","guid":{"rendered":"http:\/\/brie.com\/brian\/blog\/?p=61"},"modified":"2011-06-06T17:43:32","modified_gmt":"2011-06-07T00:43:32","slug":"using-generics-and-a-form-with-wicket","status":"publish","type":"post","link":"https:\/\/brie.com\/brian\/blog\/?p=61","title":{"rendered":"Using Generics and a Form<T> with Wicket"},"content":{"rendered":"<p>This blog post I will take a look at using a form with Wicket and binding it to an object using a PropertyModel along with Generics. I just started digging into generics in Java and even after reading a tutorial on generics, the use of &lt;T&gt; and the wildcard value &lt;?&gt; still is not completely clear to me. Yet, I think with use of Wicket, it will help my understanding and hopefully yours too. Enough fluff, I shall get to the details. The Generics add type safety and eliminate the need for casting as was originally done in the book example. <em> <\/em><\/p>\n<p>The example code for this blog can be <a href=\"http:\/\/brie.com\/brian\/wicket\/hippo02.zip\">downloaded<\/a>. This sample code is once again built upon the examples used in the book titled <a href=\"https:\/\/code.google.com\/p\/wicketinaction\/\">Wicket in Action<\/a> by Dashorst et al. The project is Maven, so if you have the <a href=\"http:\/\/www.eclipse.org\/m2e\/\">Maven Plugin<\/a> for your Eclipse, download the file, unzip it, and import the <em>File<\/em>-&gt;<em>Import-&gt;Existing Projects into Workspace<\/em>. The project name is hippo02. For this project, it has a Form and, the Customer class which along with its attributes is also composed of the Address class. The form has the coresonding html:<\/p>\n<pre>&lt;form wicket:id=\"myform\"&gt;\r\n&lt;table&gt;\r\n&lt;tr&gt;&lt;td&gt;Name&lt;\/td&gt;&lt;td&gt;&lt;input type=\"text\" wicket:id=\"name\" \/&gt;&lt;\/td&gt;&lt;\/tr&gt;\r\n&lt;tr&gt;&lt;td&gt;Street&lt;\/td&gt;&lt;td&gt;&lt;input type=\"text\" wicket:id=\"street\" \/&gt;&lt;\/td&gt;&lt;\/tr&gt;\r\n&lt;tr&gt;&lt;td colspan=\"2\"&gt;&lt;input type=\"submit\" value=\"Submit\" \/&gt;&lt;\/td&gt;&lt;\/tr&gt;\r\n&lt;\/table&gt;\r\n&lt;\/form&gt;<\/pre>\n<p>The form contains the wicket identifier <em>myform <\/em>for the form along with two other identifiers for the text fields: <em>wicket:id=&#8221;name&#8221;<\/em> and <em>wicket:id=&#8221;street&#8221;<\/em><\/p>\n<p>The two following snippets detail the classes involved: Customer and Address. A <em>Customer <\/em>has an <em>Address. <\/em>First, the Customer class. Note that the class must be made serializable so that Wicket can save state. I omitted the getters and setters. Check the hippo source if you want to see them. Next, I created the <em>Form1 <\/em>specifying the generic parameter &lt;Customer&gt;. So, when the object model is fetched as can be seen in the <em>onSubmit <\/em>method, the type does not need to be cast. Now, I was a little uncertain about the <em>TextField <\/em>portions, but it seems that they should be set as &lt;String&gt; parameters. The part that I find somewhat confusing is the specifying the class attribute and the attribute for the text field. In the <em>Form1 <\/em>class, you will note that it specifies &#8220;firstName&#8221; in the property model, and then when the TextField is created using the just created property model, it uses the value &#8220;name&#8221; that matches the wicket:id attribute given in the html.<\/p>\n<p>Now that this is all created, a Form1 object is created in the <em>Index.java <\/em>class and bound to the wicket:id attribute name &#8220;myform&#8221;.<\/p>\n<p>This is what happens when the program is run. When a Form1 is created in Index.java, a Customer object is created. When the user enters values and presses submit, the <em>onSubmit <\/em>callback action sets the values entered into the two fields.<\/p>\n<p>The plumbing seems a little tricky here, but I thought by breaking out these Anonymous Inner Classes (AIC) it would help break the details for the form. Plus, if you see a correction on the use of Generics, let me know. I hope this helps illustrate the use of PropertyModel and a Wicket Form&lt;T&gt;.<\/p>\n<p>Customer class:<\/p>\n<pre>public class Customer implements Serializable {\r\n  private String firstName;\r\n  private String lastName;\r\n  private Address address = new Address();\r\n\r\n  \/\/[snip]\r\n}<\/pre>\n<p>Address class:<\/p>\n<pre>public class Address implements Serializable {\r\n  private String name;\r\n  private String street;\r\n  private String city;\r\n  private Integer zipcode;\r\n\r\n  \/\/ [snip]\r\n}<\/pre>\n<p>Form class:<\/p>\n<pre>public class Form1 extends Form&lt;Customer&gt; {\r\n\r\n private static final long serialVersionUID = 1L;\r\n private TextField&lt;String&gt; nameField;\r\n private TextField&lt;String&gt; streetField;\r\n private PropertyModel&lt;String&gt; namePropModel;\r\n private PropertyModel&lt;String&gt; streetPropModel;\r\n private Model&lt;Customer&gt; myModel;\r\n \r\n public Form1(String id) {\r\n super(id);\r\n \r\n Customer customer = new Customer();\r\n myModel = new Model&lt;Customer&gt;(customer);\r\n setModel(myModel);\r\n \r\n namePropModel = new PropertyModel&lt;String&gt;(customer, \"firstName\");\r\n nameField = new TextField&lt;String&gt;(\"name\",namePropModel);\r\n add(nameField);\r\n \r\n streetPropModel = new PropertyModel&lt;String&gt;(customer, \"address.street\");\r\n streetField = new TextField&lt;String&gt;(\"street\", streetPropModel);\r\n add(streetField);\r\n\r\n }\r\n \r\n protected void onSubmit() {\r\n Customer customer =\u00a0 getModelObject();\r\n String street = customer.getAddress().getStreet();\r\n \/\/ do something with\/to the customer\r\n }\r\n\r\n}<\/pre>\n<p>Inclusion into Index.java:<\/p>\n<pre>Form1 myForm = new Form1(\"myform\");\r\nadd(myForm);<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This blog post I will take a look at using a form with Wicket and binding it to an object using a PropertyModel along with Generics. I just started digging into generics in Java and even after reading a tutorial &hellip; <a href=\"https:\/\/brie.com\/brian\/blog\/?p=61\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-61","post","type-post","status-publish","format-standard","hentry","category-wicket"],"_links":{"self":[{"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=\/wp\/v2\/posts\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=61"}],"version-history":[{"count":2,"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=\/wp\/v2\/posts\/61\/revisions"}],"predecessor-version":[{"id":63,"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=\/wp\/v2\/posts\/61\/revisions\/63"}],"wp:attachment":[{"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=61"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=61"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brie.com\/brian\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}