RE: Glue for composing panels
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
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
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
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
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
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
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
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
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
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