RE: Glue for composing panels

2009-11-03 Thread Frank Silbermann
Michal, I adopted your idea, but with a variation.  It is something like:

// Use this instead of WebPage for any base page whose component-tree
// construction relies on abstract or overridable methods.
//
abstract class DelayedConstructionWebPage extends WebPage {

private Boolean componentsAssembled = false;

...(preserve the standard constructors of WebPage)...

// This method's implementation will build the component tree.
// It may freely call abstract or overridable methods.
//
abstract protected void assembleComponents();

// If you have any method which accesses a component,
// and which might be called before the first rendering,
// to ensure that the component exists you should insert
// a one-line call to assembleComponentsIfNecessary()
//
protected assembleComponentsIfNecessary() {
if ( !componentsAssembled ) {
assembleComponents();
componentsAssembled = true;
}
}

@Override
void onBeforeRender() {
assembleComponentsIfNecessary();
super.onBeforeRender(); 
}
}   

I believe this will minimize the boilerplate code in the classes that provide 
the actual business value.

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

Yes Frank, model-setting method was just an example how to access a
component before onBeforeRender() executes.

I've only tried to point out that we set componentsAssembled = true in
assembleComponents() method. We call assembleComponents() from
get-method (for referenced component) to ensure that referenced
component has been created.

michal

...
 /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

Re: Glue for composing panels

2009-11-02 Thread Michal Kurtak
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



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



RE: Glue for composing panels

2009-11-02 Thread Frank Silbermann
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

Re: Glue for composing panels

2009-11-02 Thread Michal Kurtak
Yes Frank, model-setting method was just an example how to access a
component before onBeforeRender() executes.

I've only tried to point out that we set componentsAssembled = true in
assembleComponents() method. We call assembleComponents() from
get-method (for referenced component) to ensure that referenced
component has been created.

michal

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

Re: Glue for composing panels

2009-10-29 Thread Pedro Santos
Hi Frank, about your final question, the ListView class is an component that
partially use you approach: his children components are created on abstract
method implementations. This abstract is called due an condition that test
for reuseItems and size properties. And this call is originated in
onBeforeRender method.

On Thu, Oct 29, 2009 at 4:50 PM, Frank Silbermann 
frank.silberm...@fedex.com 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




-- 
Pedro Henrique Oliveira dos Santos


Re: Glue for composing panels

2009-10-29 Thread John Krasnay
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



Re: Glue for composing panels

2009-10-29 Thread Pedro Santos
Nice approach, the only missing is that you hasn't how to prevent your
component users from call addLeftNavChild after render phase at development
time. But it is no big deal, since they will get an exception at runtime...

On Thu, Oct 29, 2009 at 5:47 PM, John Krasnay j...@krasnay.ca wrote:

 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




-- 
Pedro Henrique Oliveira dos Santos


Re: Glue for composing panels

2009-10-29 Thread John Krasnay
On Thu, Oct 29, 2009 at 05:58:02PM -0200, Pedro Santos wrote:
 Nice approach, the only missing is that you hasn't how to prevent your
 component users from call addLeftNavChild after render phase at development
 time. But it is no big deal, since they will get an exception at runtime...
 

By component users do you mean subclasses? They can call it from the 
constructor.

jk

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



Re: Glue for composing panels

2009-10-29 Thread Pedro Santos

Mean other programmes

Em 29/10/2009, às 17:00, John Krasnay j...@krasnay.ca escreveu:


On Thu, Oct 29, 2009 at 05:58:02PM -0200, Pedro Santos wrote:
Nice approach, the only missing is that you hasn't how to prevent  
your
component users from call addLeftNavChild after render phase at  
development
time. But it is no big deal, since they will get an exception at  
runtime...




By component users do you mean subclasses? They can call it from  
the constructor.


jk

-
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



RE: Glue for composing panels

2009-10-29 Thread Frank Silbermann
Having sub-pages push components to the base page (where they will live
in a ListView) looks like an effective solution.

One advantage is that the writer of SubPage can add zero, one, or many
components to (in his example) leftNavChildren.  To do that with my
base-page-pull approach, the base page's abstract method would have to
return a type of, say, ListComponent.  Then the subpage's
implementation would have to return a list of the desired length (zero,
one, or many).

A minor disadvantage of John's push-approach is that the writer of the
child page would have to rely on base page documentation or code to know
that the base page can be extended in this way.  With my approach the
compiler figuratively rubs his nose in it.

Another difference is that, with John's push approach, the base page
writer must do four things for each point of extension:

(1) declare the RepeatingView variable
(2) add the repeating view in the base page constructor
(3) provide a method called by subpages to add a component
(4) provide a method called by subpages to get the component's wicket-id

In my base-page pull method, once you've invested in the small (but
nontrivial) complexity of moving component-tree creation out of the
constructor into the protected void assembleComponents() method, only
two steps are required for each point of extension:

(1) define the abstract method creating the component (or
ListComponent)
(2) call it in the base page's void assembleComponents() method. 

And perhaps the movement of component-tree construction from constructor
to assembleComponents() method could be done once and for all in a
base page of all base pages!

Since I'd want to follow this approach in panel construction as well as
page construction, I would have to move component-tree assembly to an
assembleComponents() method in my very own BasePanel extends Panel
class as well.

fs

-Original Message-
From: John Krasnay [mailto:j...@krasnay.ca] 
Sent: Thursday, October 29, 2009 2:47 PM
To: users@wicket.apache.org
Subject: Re: Glue for composing panels

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