Re: creating the web page in onInitialize()

2025-05-03 Thread Chris Colman
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?




creating the web page in onInitialize()

2025-05-03 Thread andrew goh

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?