All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gwt.advanced.client.ui.widget.AdvancedTabPanel Maven / Gradle / Ivy

There is a newer version: 2.0.9
Show newest version
/*
 * Copyright 2008-2012 Sergey Skladchikov
 *
 * 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 org.gwt.advanced.client.ui.widget;

import com.google.gwt.event.logical.shared.*;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import org.gwt.advanced.client.ui.Resizable;
import org.gwt.advanced.client.ui.widget.border.Border;
import org.gwt.advanced.client.ui.widget.border.BorderFactory;
import org.gwt.advanced.client.ui.widget.tab.ContentBorderFactory;
import org.gwt.advanced.client.ui.widget.tab.TabBorderFactory;
import org.gwt.advanced.client.ui.widget.tab.TabPosition;

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

/**
 * This is ana dvanced tab panel implementation that allows placing tabs around the content.
 *
 * @author Sergey Skladchikov
 * @since 1.4.6
 */
public class AdvancedTabPanel extends SimplePanel implements HasSelectionHandlers, HasBeforeSelectionHandlers, Resizable {
    /** tabs position for displaying */
    private TabPosition position;
    /** index of the currently selected tab */
    private int selected = -1;
    /** tabs and contents list */
    private List tabs = new ArrayList();
    /** a factory for rendering tab borders */
    private BorderFactory tabBorderFactory;
    /** a factory for rendering the content border */
    private BorderFactory contentBorderFactory;
    /** tab panel layout */
    private FlexTable layout = new FlexTable();
    /** content border instance */
    private Border contentBorder;
    /** a widget of the tabs band */
    private Widget tabsWidget;
    /** tab states list */
    private List tabStates = new ArrayList();

    /** Creates an instance of this class and displays top tabs band. */
    public AdvancedTabPanel() {
        this(TabPosition.TOP);
    }

    /**
     * Creates an instance of this class and displays the tabs band in the specified position.
     *
     * @param position is a tabs position.
     */
    public AdvancedTabPanel(TabPosition position) {
        this(position, new TabBorderFactory(), new ContentBorderFactory());
    }

    /**
     * Creates an instance of this class and displays the panel using the specified border factories.
     *
     * @param position             is a position of tabs.
     * @param tabBorderFactory     is a factory for tabs border.
     * @param contentBorderFactory is a factory for the content border.
     */
    public AdvancedTabPanel(TabPosition position, BorderFactory tabBorderFactory, BorderFactory contentBorderFactory) {
        this.tabBorderFactory = tabBorderFactory;
        this.contentBorderFactory = contentBorderFactory;
        this.position = position;

        this.layout.setStyleName("layout");
        setStyleName("advanced-TabPanel");
        render();

        addBeforeSelectionHandler(new BeforeSelectionHandler() {
            @Override
            public void onBeforeSelection(BeforeSelectionEvent event) {
                for (Object tabState1 : tabStates) {
                    TabState tabState = (TabState) tabState1;
                    if (event.getItem() == tabState.getIndex() && !tabState.isEnabled()) {
                        event.cancel();
                        return;
                    }
                }
            }
        });
    }

    /**
     * Do the same things like the
     * {@link #addTab(com.google.gwt.user.client.ui.Widget, com.google.gwt.user.client.ui.Widget)}
     * method and included into the class for changing from GWT TabPanel to this one.
     *
     * @param content is a tab content.
     * @param tab     is a tab header.
     */
    public void add(Widget content, Widget tab) {
        addTab(tab, content);
    }

    /**
     * Do the same things like the
     * {@link #setSelected(int)} method and included into the class for changing from GWT TabPanel
     * to this one.
     *
     * @param index is a selected tab index.
     */
    public void selectTab(int index) {
        setSelected(index);
    }

    /**
     * Adds a new tab into the panel.
     *
     * @param tab     is a tab widget.
     * @param content is a content widget.
     */
    public void addTab(Widget tab, Widget content) {
        TabHolder holder = new TabHolder(tab, content);
        tabs.remove(holder); // to avoid duplicated tabs
        tabs.add(holder);
        if (getSelected() == -1)
            setSelected(0);

        renderTabs();

        TabState tabState = new TabState();
        tabState.setIndex(tabs.indexOf(holder));
        tabState.setTab(tab);
        tabState.setEnabled(true);
        tabStates.add(tabState);
    }

    /**
     * Removes the tab from the panel.
     *
     * @param tab is a tab widget to identify the tab.
     */
    public void removeTab(Widget tab) {
        int index = indexOf(tab);
        tabs.remove(new TabHolder(tab, null));

        if (getSelected() == index) {
            index = index + 1;
            if (index >= tabs.size())
                index = tabs.size() - 1;
            setSelected(index);
        }
        renderTabs();

        TabState selState = null;
        for (Object tabState1 : tabStates) {
            TabState tabState = (TabState) tabState1;
            if (tabState.getTab().equals(tab))
                selState = tabState;
        }

        if (selState != null) {
            int selIndex = selState.getIndex();
            tabStates.remove(selState);

            for (Object tabState1 : tabStates) {
                TabState tabState = (TabState) tabState1;
                if (tabState.getIndex() > selIndex)
                    tabState.setIndex(tabState.getIndex() - 1);
            }
        }
    }

    /**
     * Inserts the tab before the specified tab.
     *
     * @param tab     is a tab widget.
     * @param content is a tab widget.
     * @param before  is an index of existent tab.
     */
    public void insertTab(Widget tab, Widget content, int before) {
        if (tabs.size() >= before)
            throw new IllegalArgumentException("Insertion index can't be greater the number of existing tabs");

        TabHolder holder = new TabHolder(tab, content);
        tabs.remove(holder); // to avoid duplicated tabs
        tabs.add(before, holder);

        if (getSelected() == before)
            setSelected(before + 1);
        renderTabs();

        TabState tabState = new TabState();
        tabState.setIndex(tabs.indexOf(holder));
        tabState.setTab(tab);
        tabState.setEnabled(true);
        tabStates.add(tabState);
    }

    /**
     * Sets the specified tab selected.
     *
     * @param index is an index of the tab for selection.
     */
    public void setSelected(int index) {
        if (index != selected) {
            if (index >= tabs.size())
                return;

            BeforeSelectionEvent event = BeforeSelectionEvent.fire(this, index);
            if (event.isCanceled())
                return;

            selected = index;
            renderTabs();

            SelectionEvent.fire(this, index);
            resize();
        }
    }

    /**
     * Sets the tab selected.
     *
     * @param tab is a widget of the tab to select.
     */
    public void setSelected(Widget tab) {
        setSelected(indexOf(tab));
    }

    /**
     * Gets an index of the selected tab.
     *
     * @return an index of the selected tab.
     */
    public int getSelected() {
        return selected;
    }

    /**
     * Gets the tab widget by index.
     *
     * @param index is an index of the tab.
     * @return a tab widget.
     */
    public Widget getTab(int index) {
        if (index < 0 || this.tabs.size() <= index)
            return null;
        TabHolder tabHolder = this.tabs.get(index);
        return tabHolder != null ? tabHolder.getTab() : null;
    }

    /**
     * Gets the content widget by the tab.
     *
     * @param tab is a tab widget.
     * @return a content widget.
     */
    public Widget getContent(Widget tab) {
        int index = indexOf(tab);
        if (index == -1)
            return null;
        TabHolder tabHolder = this.tabs.get(index);
        return tabHolder != null ? tabHolder.getContent() : null;
    }

    /**
     * Gets an index of the specified tab.

* If there is no such widget, returns -1. * * @param tab is a widget of the tab. * @return an index of the tab. */ public int indexOf(Widget tab) { return this.tabs.indexOf(new TabHolder(tab, null)); } /** * Gets a total count of tabs. * * @return a total count. */ public int count() { return this.tabs.size(); } /** * Sets the specified tab enabled or disabled. * * @param tabIndex is a tab index. * @param enable is a tab state value. */ public void setTabEnabled(int tabIndex, boolean enable) { Widget w = getTab(tabIndex); if (enable) { w.removeStyleName("disabled-tab"); } else { w.addStyleName("disabled-tab"); } for (Object tabState1 : tabStates) { TabState tabState = (TabState) tabState1; if (tabState.getIndex() == tabIndex) tabState.setEnabled(enable); } } /** * Gets the tabs border factory. * * @return is the tabs border factory that is currently used. */ public BorderFactory getTabBorderFactory() { return tabBorderFactory; } /** * Gets the content border factory. * * @return is the content border factory that is currently used. */ public BorderFactory getContentBorderFactory() { return contentBorderFactory; } /** * Gets a content border that is already rendered. * * @return a content border. */ public Border getContentBorder() { return contentBorder; } /** * Gets tabs position. * * @return tabs position. */ public TabPosition getPosition() { return position; } /** Renders the widget. */ protected void render() { remove(this.layout); setWidget(this.layout); if (getContentBorder() != null) this.layout.remove((Widget) getContentBorder()); this.contentBorder = getContentBorderFactory().create(); ((Widget) getContentBorder()).addStyleName("content-" + getPosition().getName()); this.layout.setWidget(1, 1, (Widget) getContentBorder()); resize(); } /** This method renders tabs band widget and puts it in the current position. */ protected void renderTabs() { if (this.tabsWidget != null) this.tabsWidget.removeFromParent(); this.tabsWidget = getPosition().getRenderer().render(this); TabPosition.LayoutPosition layoutPosition = getPosition().getLayoutPosition(); switch (layoutPosition) { case LEFT: this.layout.setWidget(1, 0, this.tabsWidget); break; case RIGHT: this.layout.setWidget(1, 2, this.tabsWidget); break; case BOTTOM: this.layout.setWidget(2, 1, this.tabsWidget); break; case TOP: default: this.layout.setWidget(0, 1, this.tabsWidget); } Element parent = DOM.getParent(((Widget) getContentBorder()).getElement()); DOM.setStyleAttribute(parent, "height", "100%"); DOM.setStyleAttribute(parent, "width", "100%"); Widget content = getContent(getTab(getSelected())); if (getSelected() != -1 && (content != this.contentBorder.getWidget() || this.contentBorder.getWidget() == null)) { getContentBorder().setWidget(getContent(getTab(getSelected()))); } } /** {@inheritDoc} */ public void resize() { Widget content = getContent(getTab(getSelected())); if (content != null && content instanceof Resizable) ((Resizable) content).resize(); } @Override public HandlerRegistration addSelectionHandler(SelectionHandler selectionHandler) { return addHandler(selectionHandler, SelectionEvent.getType()); } @Override public HandlerRegistration addBeforeSelectionHandler(BeforeSelectionHandler beforeSelectionHandler) { return addHandler(beforeSelectionHandler, BeforeSelectionEvent.getType()); } /** * The class implements a pair of widgets related to each other.

* One of them is a tab widget and another is a content widget.

* Tab widget is a key field. * * @author Sergey Skladchikov */ protected static class TabHolder { /** tab widget */ private Widget tab; /** content widget */ private Widget content; /** * Creates an instance of this class and initializes internal fields. * * @param tab is a tab widget (key). * @param content is a content widget (value). */ public TabHolder(Widget tab, Widget content) { this.tab = tab; this.content = content; } /** * Gets a tab widget. * * @return a tab widget. */ public Widget getTab() { return tab; } /** * Gets a content widget. * * @return a content widget. */ public Widget getContent() { return content; } /** {@inheritDoc} */ public boolean equals(Object o) { if (o instanceof TabHolder) { if (this == o) return true; TabHolder tabHolder = (TabHolder) o; return !(tab != null ? !tab.equals(tabHolder.tab) : tabHolder.tab != null); } else return false; } /** {@inheritDoc} */ public int hashCode() { return tab != null ? tab.hashCode() : 0; } } /** Describes the tab state (enabled or disabled. */ protected class TabState { /** tab index */ int index; /** tab header */ public Widget tab; /** enabled or disabled */ public boolean enabled; public int getIndex() { return index; } public Widget getTab() { return tab; } public boolean isEnabled() { return enabled; } public void setIndex(int index) { this.index = index; } public void setTab(Widget tab) { this.tab = tab; } public void setEnabled(boolean enabled) { this.enabled = enabled; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy