rocket.widget.client.tabpanel.TabPanel.java Source code

Java tutorial

Introduction

Here is the source code for rocket.widget.client.tabpanel.TabPanel.java

Source

/*
 * Copyright Miroslav Pokorny
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package rocket.widget.client.tabpanel;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import rocket.event.client.MouseClickEvent;
import rocket.event.client.MouseEventAdapter;
import rocket.util.client.Checker;
import rocket.widget.client.CompositeWidget;
import rocket.widget.client.Html;
import rocket.widget.client.Image;

import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * A TabPanel provides the capability to manage a number of tabs along with
 * providing listeners for the major events that may occur to an individual tab,
 * selection and closing/removal.
 * 
 * This class combines a DeckPanel to hold tab contents and a HorizontalPanel to
 * hold the tabs themselves. This class is a rewrite of the GWT provided one
 * adding a few features and fixing bugs.
 * 
 * @author Miroslav Pokorny (mP)
 */
public abstract class TabPanel extends CompositeWidget {

    protected TabPanel() {
        super();
    }

    protected void beforeCreateWidget() {
        super.beforeCreateWidget();

        this.setItems(createItems());
        this.setTabListeners(createTabListeners());
    }

    protected Widget createWidget() {
        return this.createDockPanel();
    }

    protected DockPanel getDockPanel() {
        return (DockPanel) this.getWidget();
    }

    protected int getSunkEventsBitMask() {
        return 0;
    }

    public int getCount() {
        return this.getItems().size();
    }

    public TabItem get(final int index) {
        return (TabItem) this.getItems().get(index);
    }

    public int indexOf(final TabItem item) {
        Checker.notNull("parameter:item", item);

        return this.getItems().indexOf(item);
    }

    public void add(final TabItem item, final boolean closable) {
        this.insert(this.getCount(), item, closable);
    }

    public void insert(final int beforeIndex, final TabItem item, final boolean closable) {
        Checker.notNull("parameter:item", item);

        final Widget content = item.getContent();

        final Widget tab = this.getTabBarItemWidget(item, closable);
        this.getTabBarPanel().insert(tab, 1 + beforeIndex);
        this.getContentPanel().insert(content, beforeIndex);
        this.getItems().add(beforeIndex, item);
        item.setTabPanel(this);

        // if first tab auto select it...
        if (this.getCount() == 1) {
            this.select(0);
        }
    }

    /**
     * Factory method which creates the widget that will appear within the
     * tabbar
     * 
     * @param item
     *            The item
     * @param closable
     *            A flag indicating whether or not a close button will appear
     *            within the tab.
     * @return The created widget
     */
    protected Widget getTabBarItemWidget(final TabItem item, final boolean closable) {
        Checker.notNull("parameter:item", item);

        final HorizontalPanel panel = item.getTabWidgetPanel();
        panel.setStyleName(this.getTabBarItemStyleName());

        if (closable) {
            final Html html = new Html(" ");
            html.setStyleName("");
            panel.add(html);

            final Image closeButton = this.createCloseButton();
            closeButton.addMouseEventListener(new MouseEventAdapter() {
                public void onClick(final MouseClickEvent event) {
                    TabPanel.this.closeTab(item);
                }
            });
            panel.add(closeButton);
        }
        return panel;
    }

    protected void closeTab(final TabItem tabItem) {
        final TabListenerCollection listeners = this.getTabListeners();

        final BeforeTabCloseEvent beforeClose = new BeforeTabCloseEvent();
        beforeClose.setClosing(tabItem);
        listeners.fireBeforeTabClosed(beforeClose);

        if (false == beforeClose.isCancelled()) {
            this.remove(tabItem);

            final TabCloseEvent closed = new TabCloseEvent();
            closed.setClosed(tabItem);

            listeners.fireTabClosed(closed);
        } // if
    }

    public void remove(final int index) {
        // removing the currently selectedTab and pick another.
        if (index == this.getSelectedIndex()) {
            final int widgetCount = this.getCount();
            if (widgetCount > 1) {
                int newSelected = index + 1;
                if (newSelected == widgetCount) {
                    newSelected = index - 1;
                }
                this.select(newSelected);
            }
        }
        final TabBarPanel tabPanel = this.getTabBarPanel();
        tabPanel.remove(tabPanel.getWidget(index + 1));

        final DeckPanel contentPanel = this.getContentPanel();
        contentPanel.remove(contentPanel.getWidget(index));

        final TabItem item = (TabItem) this.getItems().remove(index);
        item.clearTabPanel();
    }

    public boolean remove(final TabItem item) {
        Checker.notNull("parameter:item", item);

        final int index = this.indexOf(item);
        if (-1 != index) {
            this.remove(index);
        }
        return index != -1;
    }

    public Iterator iterator() {
        return this.getItems().iterator();
    }

    /**
     * This list contains the individual items
     */
    private List items;

    protected List getItems() {
        Checker.notNull("field:items", this.items);
        return this.items;
    }

    protected void setItems(final List items) {
        Checker.notNull("parameter:items", items);
        this.items = items;
    }

    protected List createItems() {
        return new ArrayList();
    }

    protected abstract String getTabBarItemStyleName();

    protected abstract String getTabBarItemLabelStyleName();

    protected Image createCloseButton() {
        final Image image = new Image();
        image.setStyleName(this.getTabBarItemWidgetStyleName());

        image.setUrl(this.getCloseButtonImageUrl());
        return image;
    }

    protected abstract String getTabBarItemWidgetStyleName();

    /**
     * The url of the close image.
     */
    private String closeButtonImageUrl;

    public String getCloseButtonImageUrl() {
        Checker.notEmpty("field:closeButtonImageUrl", closeButtonImageUrl);
        return closeButtonImageUrl;
    }

    public void setCloseButtonImageUrl(final String closeButtonImageUrl) {
        Checker.notEmpty("parameter:closeButtonImageUrl", closeButtonImageUrl);
        this.closeButtonImageUrl = closeButtonImageUrl;
    }

    /**
     * Retrieves the index of the currently selected tab.
     */
    public int getSelectedIndex() {
        return this.getContentPanel().getVisibleWidget();
    }

    public void select(final TabItem item) {
        this.select(this.indexOf(item));
    }

    public void select(final int index) {
        final TabItem newlySelectedItem = this.get(index);
        TabItem previousSelection = null;
        final int previouslySelectedIndex = this.getSelectedIndex();
        if (-1 != previouslySelectedIndex) {
            previousSelection = this.get(previouslySelectedIndex);
        }

        final BeforeTabSelectEvent beforeSelected = new BeforeTabSelectEvent();
        beforeSelected.setCurrentSelection(previousSelection);
        beforeSelected.setNewSelection(newlySelectedItem);

        final TabListenerCollection listeners = this.getTabListeners();
        listeners.fireBeforeTabSelected(beforeSelected);

        if (false == beforeSelected.isCancelled()) {
            final String selectedStyle = this.getTabBarItemSelectedStyleName();

            final TabBarPanel tabBarPanel = this.getTabBarPanel();
            final DeckPanel contentPanel = this.getContentPanel();

            // find the previously selected tab. and unselect it.
            final int previousIndex = contentPanel.getVisibleWidget();
            TabItem previouslySelectedTabItem = null;
            if (-1 != previousIndex) {
                final Widget tab = tabBarPanel.getWidget(previousIndex + 1);
                tab.removeStyleName(selectedStyle);
                previouslySelectedTabItem = this.get(previousIndex);
            }

            // apply the style to the new tab.
            final Widget tabBarItemPanel = tabBarPanel.getWidget(index + 1);
            tabBarItemPanel.addStyleName(selectedStyle);

            // tell the deckPanel to select a new sub-widget.
            contentPanel.showWidget(index);

            final TabSelectEvent selectedEvent = new TabSelectEvent();
            selectedEvent.setPreviouslySelected(previouslySelectedTabItem);
            selectedEvent.setCurrentSelection(newlySelectedItem);

            listeners.fireTabSelected(selectedEvent);
        }
    }

    protected abstract String getTabBarItemSelectedStyleName();

    /**
     * This panel contains both the TabBar and contents panel.
     */
    protected DockPanel getPanel() {
        return (DockPanel) this.getWidget();
    }

    protected DockPanel createDockPanel() {
        final DockPanel dockPanel = new DockPanel();

        final TabBarPanel tabBarPanel = this.createTabBarPanel();
        dockPanel.add((Widget) tabBarPanel, getTabBarDockPanelConstants());

        final DeckPanel contentPanel = this.createContentPanel();

        dockPanel.add(contentPanel, DockPanel.CENTER);
        dockPanel.setCellHeight(contentPanel, "100%");
        dockPanel.setCellWidth(contentPanel, "100%");

        return dockPanel;
    }

    abstract DockPanel.DockLayoutConstant getTabBarDockPanelConstants();

    /**
     * This panel is used to house tab title widgets.
     */

    protected TabBarPanel getTabBarPanel() {
        return (TabBarPanel) this.getDockPanel().getWidget(Constants.TAB_BAR_PANEL_INDEX);
    }

    protected abstract TabBarPanel createTabBarPanel();

    /**
     * A DeckPanel is used to house all tab content. The selected tab selects
     * the appropriate item from the deckPanel to be visible.
     */

    public DeckPanel getContentPanel() {
        return (DeckPanel) this.getDockPanel().getWidget(Constants.DECK_PANEL_INDEX);
    }

    protected DeckPanel createContentPanel() {
        final DeckPanel panel = new DeckPanel();
        panel.setStyleName(getContentPanelStyleName());
        return panel;
    }

    protected abstract String getContentPanelStyleName();

    // LISTENERS
    // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    /**
     * A collection of TabListeners who will in turn be notified of all
     * TabListener events.
     */
    private TabListenerCollection tabListeners;

    protected TabListenerCollection getTabListeners() {
        Checker.notNull("field:tabListeners", this.tabListeners);
        return this.tabListeners;
    }

    protected void setTabListeners(final TabListenerCollection tabListeners) {
        Checker.notNull("parameter:tabListeners", tabListeners);
        this.tabListeners = tabListeners;
    }

    protected TabListenerCollection createTabListeners() {
        return new TabListenerCollection();
    }

    public void addTabListener(final TabListener listener) {
        Checker.notNull("parameter:listener", listener);
        this.getTabListeners().add(listener);
    }

    public void removeTabListener(final TabListener listener) {
        this.getTabListeners().remove(listener);
    }

    /**
     * This interface includes the common public methods from the
     * HorizontalPanel and VerticalPanel classes.
     * 
     * @author Miroslav Pokorny (mP)
     */
    static interface TabBarPanel {
        void add(Widget widget);

        void insert(Widget widget, int beforeIndex);

        Widget getWidget(int index);

        int getWidgetCount();

        int getWidgetIndex(Widget child);

        boolean remove(int index);

        boolean remove(Widget widget);
    }

    /**
     * The classes below are necessary so that HorizontalPanel and VerticalPanel
     * can share a common interface.
     */
    static class HorizontalTabBarPanel extends HorizontalPanel implements TabBarPanel {
    }

    static class VerticalTabBarPanel extends VerticalPanel implements TabBarPanel {

    }
}