If I understand you correctly, Michal, you don't want to set the component's 
model once and for all as it is being created, and you're worried that the 
model-setting method might be called before the first onBeforeRender().

That's just an example, I guess, so perhaps the general concern is that you 
might need to access a component for whatever reason before the first call to 
onBeforeRender().

Therefore, _any_ attempt to access a component after constructors have 
terminated should trigger construction of the component tree if necessary.

Is that the idea?

It sure would be nice to have an honest to goodness post-constructors event on 
which I could hang the component tree creation -- then we wouldn't have to 
worry about this.

In my use of Wicket, I've always set a component's model at the time that 
component was created -- I've never had to swap out a model in a separate 
operation.  If the data to be displayed changes dynamically, I've always simply 
used a model which took that into account.

Is that just a different style of programming?  Or are there circumstances 
beyond my limited experience which would require one to access a component 
before the first call to onBeforeRender()?  

/Frank

-----Original Message-----
From: Michal Kurtak [mailto:michal.kur...@gmail.com] 
Sent: Monday, November 02, 2009 3:39 AM
To: users@wicket.apache.org
Subject: Re: Glue for composing panels

Hi Frank,

We use the same approach as you. We have found one disadvantage, which
relates to references to components created by subclasses.
I'll demostrate it (problem and solution) in the following example:

class BasePage extends Page
{
   /** Component created by subclass */
   private Component component;
   private boolean componentsAssembled = false;

    /** Let the assemple method to set componentsAssembled flag */
    private void assembleComponents()
    {
        component = createComponent();
        ...
        componentsAssembled = true;
    }

    protected abstract Component createComponent();

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

   /** Method uses assambelComponents() to ensure, that component is created */
   public Component getComponent()
   {
       if(component == null)
       {
              assembleComponents();
       }
       return component;
   }

   /** public method delegete to referenced component. Uses safe
getComponent() method  */
   public void setComponentModel(IModel<?> model)
   {
     getComponent().setModel(model);
   }



michal


2009/10/29 Frank Silbermann <frank.silberm...@fedex.com>:
>
> 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