Using onInitialize() to establish components instead of the constructor makes sense for many reasons.

One of the most important reasons is what we discovered in the early days of Wicket: the code executed in a constructor is executing before the object is fully constructed i.e. before virtual method tables are ready for use.

This means that if your page or panel is part of a class hierarchy and you rely on overridden methods they will not always perform correctly.

However, because onInitialize() is called by the Wicket framework after construction, all overridden methods will perform correctly.

We were using an overridden getVariation() method in our Page class hierarchy and things weren't working when calling that method in the constructor (which is why, many years ago, we asked the awesome Wicket devs to introduce a separate overridable onInitialize() method called after construction - which they did! - and everything was awesome for us after that =] ).

Something else that may help your need to implement flexible assembling of components: dynamic component creation.

This basically means that your component hierarchy can be dynamically assembled, as dictated by the markup. i.e. add a new panel to a page's markup using a specific component Id and during page rendering the appropriate Java component will be automatically instantiated and added to the parent.

The implementation of this feature was non trivial but has been so useful it has paid off big time.

Basic concept:

Implement a class called ComponentLibraryResolver which has a static method addDynamicComponents(MarkupContainer container, DomainSpecifcEntity domainSpecificEntity)

Have 'BasePage' that all pages in your app derive from.

In BasePage.onInitialize() calls ComponentLibraryResolver.addDynamicComponents(this, myDomainSpecificEntity);

addDynamicComponents analyses the preparsed markup, looking for tagIds that are marked to be auto created and any that it finds get created and added to the container.

That's a bit oversimplified but you get the idea.

I think there is an interface in Wicket that allows you 'hook into' the component creation part of the page rendering lifecycle but we ended up not being able to use that for our use case ... from memory it might have been due to our need to pass in our DomainSpecificEntity.

Regards,
Chris

On 4/05/2025 2:09 am, andrew goh wrote:
While working on an Apache Wicket app, I have some questions.

The example in the user guide(s) tend to put all the creation of the page's component in the constructor()

https://nightlies.apache.org/wicket/guide/9.x/single.html#_the_homepage_class

However, I'm seeing that that approach has some downsides. For more complex components e.g. forms or complex panels with many embedded components (e.g. reusable tables forms, page layouts (e.g. menus)  etc). Sometimes a lot of parameters are passed to the constructor to fill up the page / component. There are often cases that some components has various options or optional components. Currently, I'm handling that by declaring different constructors so that the basic ones may have less parameters, and where the options or optional components are needed, they are passed into the page via constructors with more parameters.

Another downside is a javabean styled component where one can have a no args constructor. And that the various parameters are updated using getters and setters methods, e.g. with commons beanutils (https://commons.apache.org/proper/commons-beanutils/).

I'm thinking about implementing component construction i.e. initializing the various page components using onInitialize() https://nightlies.apache.org/wicket/guide/9.x/single.html#_hook_methods_for_component_lifecycle

That means say if the web page codes looks like

public class HomePage extends WebPage {
    public HomePage() {
       add(new Label("helloMessage", "Hello WicketWorld!"));
    }
}

it becomes

@Override
protected void onInitialize() {
        super.onInitialize();
        add(new Label("helloMessage", "Hello WicketWorld!"));

}

In fact, rather than pages, it is more likely that I use that with components and override onInitialize().

In that sense, components can be constructed 'javabeans' style say using a no args constructor and its properties set using getter and setter methods.

Is this feasible, has anyone done this in an actual app?


Reply via email to