Rather than having the base class "pull" in components from the subclass,
recently I've been tackling this kind of problem by creating RepeatingViews in
the base class and letting subclasses "push" components in by adding to the
repeating view:

    <div class="leftNav">
      <div wicket:id="leftNavChild" class="leftNavChild"></div>
    </div>

    public class BasePage extends WebPage {
        private RepeatingView leftNavChildren;
        public BasePage() {
            add(leftNavChildren = new RepeatingView("leftNavChild"));
        }
        protected void addLeftNavChild(Component child) {
            leftNavChildren.add(child);
        }
        protected String newLeftNavChildId() {
            return leftNavChildren.newChildId();
        }
    }

    public class SubPage extends BasePage {
        public SubPage() {
            addLeftNavChild(new MyNavPanel(newLeftNavChildId()));
        }
    }

jk

On Thu, Oct 29, 2009 at 01:50:06PM -0500, Frank Silbermann wrote:
> 
> 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
> 

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

Reply via email to