1
votes

I've started an application wit a lot of forms in with Wicket so I'm looking for how to write components well, reusable and mainly, easy to maintain.

Reading best practices from the guide it says to decouple more complex components (in the example a form with labels and panels) make it self-contained defining a method to create each form component:

public class BlogEditPage extends WebPage {
...
    private Form<Blog> createBlogEditForm() {
        Form<Blog> form = newBlogEditForm();
        form.add(createHeadlineField());
        form.add(createContentField());
        form.add(createTagField());
        form.add(createViewRightPanel());
        form.add(createCommentRightPanel());
        form.setOutputMarkupId(true);
        return form;
    }

    // more methods here
}

At first it sounds weird to me, but considering each component can have it's own complexity, validation rules, it makes sense (this way it can be easily reused too).

But in the same section it also says to not create factories to components.. now it's weird cause the snippet above works like a factory to forms, and the page have factories to form components. Even the methods that creates form components being private, only form will can use it, and reusability is lost. So considering the second recommendation, these methods (that is implicit component factories) are not a good practice.

Any clarification of how to create complex components are welcome (with some code example will be better).

Thanks in advance.

1

1 Answers

2
votes

We use this approach and it works ok.

The methods you show are not factories. Look at the example from the docs. They have something like LabelFactory.createLabel(id, model); But that's not the case with the methods you have shown above.

In the methods you show remove the word create. Our components look like this:

   private AjaxFallbackDefaultDataTable table() {
      List<AbstractColumn> columns = new ArrayList<>();
      columns.add(new PropertyColumn(Model.of("Login"), "login", "login"));
      columns.add(new PropertyColumn(Model.of("First Name"), "firstName", "firstName"));
      columns.add(new PropertyColumn(Model.of("Last Name"), "lastName", "lastName"));
      AjaxFallbackDefaultDataTable dt = new AjaxFallbackDefaultDataTable("table", columns, new UserProvider(), 50);
      dt.setOutputMarkupPlaceholderTag(true);
      return dt;
   }

There is no factory. An additional convention we use is that the name of the method and the wicket id of the components has to be the same. This eases navigation in code.