Thanks for the input, I have a couple of quick questions for you regarding this implementation:


<wicket:panel>
    <span wicket:id="current">Current Component</span>
</wicket:panel>

public class AlternatablePanel extends UserPanel
{

    private static Log log = LogFactory.getLog(AlternatablePanel.class);

    IAlternatable alternatable;

    public static final String COMPONENT_ID = "current";

    public AlternatablePanel(String string, IAlternatable alternatable )
    {
        super(string);

        this.alternatable = alternatable;

        add( alternatable.getAlternateComponent( COMPONENT_ID ) );
    }

    @Override
    protected void onBeforeRender()
    {
        replace( alternatable.getAlternateComponent( COMPONENT_ID ) );
        super.onBeforeRender();
    }
}

That is my initial attempt Panel that will try to render based on the the component returned from the IAlternatable interface:

public interface IAlternatable
{
    public Panel getAlternateComponent( String id );
}


The problem I'm running into is that because I must pass the id through the interface, I must also construct the components from the interface method?  Here's what I have right now:

        add( seriesEditor = new AlternatablePanel( "series.editor", new IAlternatable() {

            public Panel getAlternateComponent(String id)
            {
                 if ( blockEditor.getSelectedItem() != null )
                 {
                     return new SeriesEditPanel( id,
                                                 new PropertyModel( blockEditor, "selectedItem.item" ),
                                                 new PropertyModel( streetEditor, "items"),
                                                 EditAddressesPanel.this );
                 } else {
                     return new EmptyPanel( id, "You must select a block on the left" );
                 }
            }

        }) );

The reason for this is I need the id upon creation of the sub-panels.  I can't specify them from the parent.  Now I either have to concrete the IAlternatable with specific accessors for my sub-panels, or.. what I'd *like* to do is implement the interface directly:

public Panel getAlternateComponent()
{
    if ( items.size() == 0 )  
        return EmptyPanel( this.getMarkupId(), "There are no items to display" );
    else 
        return this;
}

But the problem here is the markupID.  How can I get the proper markupID to the component at *construction* time, so that I don't have to construct the object from the interface method (it's actually not possible for me to do since I have a set of 4-5 dependant panels who's models are dependant on each other).  What I'm looking to avoid is circumstances where I need to spend 10-15 lines of code to wire up an anonymous class to handle component-swapping while keeping each component accessible to the outside world (if that makes any sense). 


Aaron


On Fri, 2006-04-28 at 08:07 -0700, Igor Vaynberg wrote:
look at the way TabbedPanel works. it gets a list of any number of panels and then swaps them so the right panel i shown for the selected tab.

as far as your interface goes you can do something like this:

String componentId="altcomp";
Component c=getAlternateComponent(componentId);
if (c!=null) {
   add(c);
} else {
   add(new WebMarkupContainer(altcomp).setVisible(false));
}

and in markup
<span wicket:id="altcomp">alternative component</span>

since the markup is fixed you should change the interface to return a panel because not all components can be attached to a span tag.

public interface IAlternatable
{
    public Panel getAlternateComponent(String componentId);
}

this should get you started

-Igor



On 4/28/06, Aaron Hiniker <[EMAIL PROTECTED]> wrote:
I searched the lists and found one other question about if/else component rendering.  It didn't really provide any examples, only suggestions to use Visibility flagging or a component factory to get "swappable panels" within a border.  Can I see an example of this "component factory"?  What I had initially planned is a panel/border component that will take a component and render it.  It would take an instance of an interface like this:

public interface IAlternatable
{
    public Component getAlternateComponent();
}

and render only the component that is returned from the interface.  I tried a few combinitions of visibility flagging/heirarchy modifications, but I can't modify the heirarchy in onBeforeRender() by Wicket design and visibility hacks screwed with my AJAX updates.  Are there any examples of selecting which component to render at runtime in an generic way.  Case scenarios I can think of that I would like to implement this with would be:

A component that can display itself, or a "No Items Selected" panel based on it's selection model

A tab panel or similar that can update it's "body" content based on the selected tab.  I saw a tab panel in the examples, but the tabs where hard-coded panels (panel1, panel2, panel3, etc).  I'm looking for a generic, clean method to do something similar... with AJAX too.

Sorry if I missed something obvious...


Aaron

Reply via email to