I was discussing glue for composing reusable panels into web pages on
the blog of Erik van Oosten
(http://blog.jteam.nl/2009/09/16/wicket-dos-and-donts/).

I told him that my approach had been to create an abstract base page
that constructs the common elements while leaving place-holders for
page-specific panels by defining methods such as:

        abstract Panel createUpperLeftPanel (String wicketID);
        abstract Panel createLowerRightPanel(String wicketID);

and having the base page's constructor say things like:

        Panel p1 = createUpperLeftPanel("a_wicket_id");
        add(p1);
        ...
        Add( createUpperRightPanel("another_wicket_id") );

The child page's contribution would be the implementation of the
abstract methods.
 
I explained that I preferred this to mark-up inheritance because I could
add to the base page in any number places (not just one place), the
compiler would tell the child-page writer exactly what panels were
needed, and most importantly, no additional mark-up whatsoever would
need to be associated with any of the child pages.  (Panel classes used
by the child page would of course have their associated mark-up.)  

Eric and others explained what a bad idea it is for constructors to call
overridable methods -- they execute before the child-page's properties
have been set.  I usually got away with this, but I admit I was burnt a
few times.  Recently, I wondered whether there might be a simple fix for
the constructor-calls-overridable-method problem, such as:

(a) Move the base page's component tree construction out of the
constructor, and put it into the method:

        private void assembleComponents() {
                ...
        }

(b) Add the property:

        private boolean componentsAssembled = false;

(c) Override as follows to construct the component tree after the class
constructors finish:

        @Override
        void onBeforeRender() {
                if ( !componentsAssembled ) {
                        assembleComponents();
                        componentsAssembled = true;
                }
                super.onBeforeRender(); // Or whatever else is needed
        }

Then component construction would wait until the properties in both the
parent and the subclass had been set.  I'd no longer have the problem
associated with calling abstract methods from the constructor.

Do you see any disadvantages to this approach? Is there a more
appropriate hook upon which to hang my base page's component-tree
assembly?

If it _is_ a good approach, is there any reason the Wicket designers
chose not to create an overrideable method in the Component class that
is called just once after constructors terminate, and tell developers
that this is where the component tree should be created?

/Frank

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to