1
votes

recently i needed to determine the visibility of a component depending on the visibilty of the respective child components (container should be visible if at least one child is visible). Due to the fact i'm setting the visibility of every component in the respective onConfigure()-methods i cant use this method to fullfil my needs. So i switched into the onBeforeRender-methods and did the job there -> works great. After that i wanted to extract this into a behavior since this is more reusable. Still i cant use the onconfigure-method and i tried the respective beforeRender-method. But now wicket throws an exception claiming

"Cannot modify component hierarchy after render phase has started (page version cant change then anymore)"

I think either the naming or the behavior of this method is weird. Is there no possibility to solve this with a behavior? :(

What do u think?

2

2 Answers

1
votes

I would probably override the container's isVisible() method to call the isVisible() method of all its children (or at least until one of them returns true).

I prefer overriding isVisible() in general unless visibility depends on outside factors (i.e. anything other than the component's model or its children). It's much more readable this way. Obviously what you have to watch out for if you do this is to never call expensive operations in your isVisible() implementation.

0
votes

Have a look at EnclosureContainer which implements exactly what you ask, but for a single child. It should be easy to extend to multiple children.

The trick is to call the children's onConfigure method in the container's isVisible():

public boolean isVisible()
{
    child.configure();
    return child.determineVisibility();
}

From Component#onConfigure():

     * EG to link visiliby of
     * two markup containers the following should be done:
     * 
     * 
     * final WebMarkupContainer source=new WebMarkupContainer("a") {
     *  protected void onConfigure() {
     *    setVisible(Math.rand()>0.5f);
     *  }
     * };
     * 
     * WebMarkupContainer linked=new WebMarkupContainer("b") {
     *  protected void onConfigure() {
     *      source.configure(); // make sure source is configured
     *      setVisible(source.isVisible());
     *  }
     * }

This is based on Wicket 1.5