Echo3LazyTabPane

Echo3Extras provides a nice Tab-Pane-Component, but you can run into issues with the default Tab-Pane and lots of tabs with lots of content, because the Tabs aren't created lazily (= rendered on first selection). Per default all Tabs are rendered at application startup which can degrade user experience. So we'll need to create a LazyTabPane which renders Tabs just in time (= when the user selects the Tab for the first time).

And here we go. First we create a new Component called LazyTabPane in a package jfix.echo:

package jfix.echo;

import nextapp.echo.app.Component;
import nextapp.echo.app.Composite;
import nextapp.echo.extras.app.event.TabPaneEvent;
import nextapp.echo.extras.app.event.TabSelectionListener;
import nextapp.echo.extras.app.layout.TabPaneLayoutData;

public class LazyTabPane extends nextapp.echo.extras.app.TabPane {

        public static abstract class LazyTab extends Composite {
                public LazyTab(String title) {
                        TabPaneLayoutData layout = new TabPaneLayoutData();
                        layout.setTitle(title);
                        setLayoutData(layout);
                }

                public abstract Component get();
        }
        
        public LazyTabPane() {
                addTabSelectionListener(new TabSelectionListener() {
                        public void tabSelected(TabPaneEvent event) {
                                Component selectedComponent = getComponent(getActiveTabIndex());
                                if (selectedComponent instanceof LazyTab) {
                                        initTab((LazyTab) selectedComponent);
                                }
                        }
                });
        }

        public void add(LazyTab tab) {
                super.add(tab);
                if (getComponentCount() == 1) {
                        initTab(tab);
                }
        }

        private void initTab(LazyTab tab) {
                Component component = (Component) tab.get();
                component.setLayoutData(tab.getLayoutData());
                int index = indexOf(tab);
                remove(tab);
                add(component, index);
        }
}

And here's a demo to see how things need to be wired up. The most important step is to add Lazy-Tab-components (which need to implement the #get-Method where the content should be created) to your LazyTabPane.

import jfix.echo.LazyTabPane;
import jfix.echo.LazyTabPane.LazyTab;
import nextapp.echo.app.ApplicationInstance;
import nextapp.echo.app.Component;
import nextapp.echo.app.ContentPane;
import nextapp.echo.app.Label;
import nextapp.echo.app.Window;
import nextapp.echo.webcontainer.WebContainerServlet;

public class LazyTabPaneDemoServlet extends WebContainerServlet {

        public ApplicationInstance newApplicationInstance() {
                return new ApplicationInstance() {
                        public Window init() {

                                LazyTabPane tabPane = new LazyTabPane();
                                for (int i = 0; i < 10; i++) {
                                        final int tabIndex = i;
                                        tabPane.add(new LazyTab("" + tabIndex) {
                                                public Component get() {
                                                        System.out.println("Init: " + tabIndex);
                                                        return new Label("Label " + tabIndex);
                                                }
                                        });
                                }

                                ContentPane contentPane = new ContentPane();
                                contentPane.add(tabPane);

                                Window window = new Window();
                                window.setContent(contentPane);
                                return window;
                        }
                };
        }
}

Hope this helps...

last edited 2008-04-14 16:50:32 by mjablonski