/*
* Copyright 2009 Google Inc.
*
* 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 com.cedarsolutions.client.gwt.custom.tab;
import java.util.ArrayList;
import java.util.Iterator;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
import com.google.gwt.event.logical.shared.HasBeforeSelectionHandlers;
import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.layout.client.Layout.Alignment;
import com.google.gwt.layout.client.Layout.AnimationCallback;
import com.google.gwt.resources.client.CommonResources;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.user.client.ui.AnimatedLayout;
import com.google.gwt.user.client.ui.DeckLayoutPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IndexedPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.ProvidesResize;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.gwtplatform.idhandler.client.HasElementId;
/**
* A panel that represents a tabbed set of pages (CUSTOMIZED).
*
* <h3>
* Code Source
* </h3>
*
* <p>
* This is customized code that that was directly copied from GWT under the terms of its license.
* </p>
*
* <blockquote>
* <table border="1" cellpadding="5" cellspacing="0">
* <tbody>
* <tr>
* <td><i>Source:</i></td>
* <td>{@link com.google.gwt.user.client.ui.TabLayoutPanel}</td>
* </tr>
* <tr>
* <td><i>Version:</i></td>
* <td>GWT 2.4.0</td>
* </tr>
* <tr>
* <td><i>Date:</i></td>
* <td>March, 2011</td>
* </tr>
* <tr>
* <td><i>Purpose:</i></td>
* <td>GWT's standard tab panel does not support legible element ids for tabs</td>
* </tr>
* </tbody>
* </table>
* </blockquote>
*
* <p>
* The code was copied rather than extended because the original GWT code
* does not faciliate extension. GWT code is often difficult to extend due
* to design choices like the use of private or final variables, methods,
* or dependent classes.
* </p>
*
* <p>
* <b>This class DOES NOT WORK with UI binder layout, except for defining
* the location of the tab panel itself.</b> You cannot use UI binder to lay out
* the tabs within this panel. This is because GWT does not know how to parse
* the UI binder layout into a class of this type. See also
* <a href="http://groups.google.com/group/google-web-toolkit/browse_thread/thread/f86bd3c0ca3ac212">Google Groups</a>
* and <a href="http://stackoverflow.com/questions/5223352/gwt-uiconstructor-with-arguments-class-has-no-appropriate-setter-method">StackOverflow</a>.
* </p>
*
* <h3>
* Original Documentation
* </h3>
*
* <p>
* A panel that represents a tabbed set of pages, each of which contains another
* widget. Its child widgets are shown as the user selects the various tabs
* associated with them. The tabs can contain arbitrary text, HTML, or widgets.
* </p>
*
* <p>
* This widget will <em>only</em> work in standards mode, which requires that
* the HTML page in which it is run have an explicit <!DOCTYPE>
* declaration.
* </p>
*
* <h3>CSS Style Rules</h3>
* <dl>
* <dt>.gwt-TabLayoutPanel
* <dd>the panel itself
* <dt>.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs
* <dd>the tab bar element
* <dt>.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab
* <dd>an individual tab
* <dt>.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabInner
* <dd>an element nested in each tab (useful for styling)
* <dt>.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent
* <dd>applied to all child content widgets
* </dl>
*
* <h3>Use in UiBinder Templates</h3>
* <p>
* A TabLayoutPanel element in a UiBinder template must have a <code>barHeight</code> attribute with a double
* value, and may have a <code>barUnit</code> attribute with a
* {@link com.google.gwt.dom.client.Style.Unit Style.Unit} value.
* <code>barUnit</code> defaults to PX.
* <p>
* The children of a TabLayoutPanel element are laid out in <g:tab>
* elements. Each tab can have one widget child and one of two types of header
* elements. A <g:header> element can hold html, or a <g:customHeader>
* element can hold a widget. (Note that the tags of the header elements are
* not capitalized. This is meant to signal that the head is not a runtime
* object, and so cannot have a <code>ui:field</code> attribute.)
* <p>
* For example:<pre>
* <g:TabLayoutPanel barUnit='EM' barHeight='3'>
* <g:tab>
* <g:header size='7'><b>HTML</b> header</g:header>
* <g:Label>able</g:Label>
* </g:tab>
* <g:tab>
* <g:customHeader size='7'>
* <g:Label>Custom header</g:Label>
* </g:customHeader>
* <g:Label>baker</g:Label>
* </g:tab>
* </g:TabLayoutPanel>
* </pre>
*/
public class TabLayoutPanel extends ResizeComposite implements HasWidgets,
ProvidesResize, IndexedPanel.ForIsWidget, AnimatedLayout,
HasBeforeSelectionHandlers<Integer>, HasSelectionHandlers<Integer>, HasElementId {
private class Tab extends SimplePanel implements HasElementId {
private Element inner;
private boolean replacingWidget;
public Tab(Widget child) {
super(Document.get().createDivElement());
getElement().appendChild(inner = Document.get().createDivElement());
setWidget(child);
setStyleName(TAB_STYLE);
inner.setClassName(TAB_INNER_STYLE);
getElement().addClassName(CommonResources.getInlineBlockStyle());
}
public HandlerRegistration addClickHandler(ClickHandler handler) {
return addDomHandler(handler, ClickEvent.getType());
}
@Override
public boolean remove(Widget w) {
/*
* Removal of items from the TabBar is delegated to the TabLayoutPanel to
* ensure consistency.
*/
int index = tabs.indexOf(this);
if (replacingWidget || index < 0) {
/*
* The tab contents are being replaced, or this tab is no longer in the
* panel, so just remove the widget.
*/
return super.remove(w);
} else {
// Delegate to the TabLayoutPanel.
return TabLayoutPanel.this.remove(index);
}
}
public void setSelected(boolean selected) {
if (selected) {
addStyleDependentName("selected");
} else {
removeStyleDependentName("selected");
}
}
@Override
public void setWidget(Widget w) {
replacingWidget = true;
super.setWidget(w);
replacingWidget = false;
}
@Override
protected com.google.gwt.user.client.Element getContainerElement() {
return inner.cast();
}
// Added for Cedar Common
@Override
public void setElementId(String elementId) {
this.getElement().setId(elementId);
}
// Added for Cedar Common
@Override
public String getElementId() {
return this.getElement().getId();
}
}
/**
* This extension of DeckLayoutPanel overrides the public mutator methods to
* prevent external callers from adding to the state of the DeckPanel.
* <p>
* Removal of Widgets is supported so that WidgetCollection.WidgetIterator
* operates as expected.
* </p>
* <p>
* We ensure that the DeckLayoutPanel cannot become of of sync with its
* associated TabBar by delegating all mutations to the TabBar to this
* implementation of DeckLayoutPanel.
* </p>
*/
private class TabbedDeckLayoutPanel extends DeckLayoutPanel {
@Override
public void add(Widget w) {
throw new UnsupportedOperationException(
"Use TabLayoutPanel.add() to alter the DeckLayoutPanel");
}
@Override
public void clear() {
throw new UnsupportedOperationException(
"Use TabLayoutPanel.clear() to alter the DeckLayoutPanel");
}
@Override
public void insert(Widget w, int beforeIndex) {
throw new UnsupportedOperationException(
"Use TabLayoutPanel.insert() to alter the DeckLayoutPanel");
}
@Override
public boolean remove(Widget w) {
/*
* Removal of items from the DeckLayoutPanel is delegated to the
* TabLayoutPanel to ensure consistency.
*/
return TabLayoutPanel.this.remove(w);
}
protected void insertProtected(Widget w, int beforeIndex) {
super.insert(w, beforeIndex);
}
protected void removeProtected(Widget w) {
super.remove(w);
}
}
private static final String CONTENT_CONTAINER_STYLE = "gwt-TabLayoutPanelContentContainer";
private static final String CONTENT_STYLE = "gwt-TabLayoutPanelContent";
private static final String TAB_STYLE = "gwt-TabLayoutPanelTab";
private static final String TAB_INNER_STYLE = "gwt-TabLayoutPanelTabInner";
private static final int BIG_ENOUGH_TO_NOT_WRAP = 16384;
private final TabbedDeckLayoutPanel deckPanel = new TabbedDeckLayoutPanel();
private final FlowPanel tabBar = new FlowPanel();
private final ArrayList<Tab> tabs = new ArrayList<Tab>();
private int selectedIndex = -1;
private Double barHeight = null;
private Unit barUnit = null;
private LayoutPanel panel = null;
/**
* Creates an empty tab panel.
*
* @param barHeight the size of the tab bar
* @param barUnit the unit in which the tab bar size is specified
*/
// Added for Cedar Common
public TabLayoutPanel(double barHeight, String barUnit) {
this();
this.setBarHeight(barHeight);
this.setBarUnit(barUnit);
}
/**
* Creates an empty tab panel.
*
* @param barHeight the size of the tab bar
* @param barUnit the unit in which the tab bar size is specified
*/
public TabLayoutPanel(double barHeight, Unit barUnit) {
this();
this.setBarHeight(barHeight);
this.setBarUnit(barUnit);
}
/**
* Creates an empty tab panel.
*/
// Added for Cedar Common
public TabLayoutPanel() {
this.panel = new LayoutPanel();
initWidget(panel);
// Add the tab bar to the panel.
panel.add(tabBar);
// Add the deck panel to the panel.
deckPanel.addStyleName(CONTENT_CONTAINER_STYLE);
panel.add(deckPanel);
// Make the tab bar extremely wide so that tabs themselves never wrap.
// (Its layout container is overflow:hidden)
tabBar.getElement().getStyle().setWidth(BIG_ENOUGH_TO_NOT_WRAP, Unit.PX);
tabBar.setStyleName("gwt-TabLayoutPanelTabs");
setStyleName("gwt-TabLayoutPanel");
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void add(IsWidget w) {
add(asWidgetOrNull(w));
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void add(IsWidget w, IsWidget tab) {
add(asWidgetOrNull(w), asWidgetOrNull(tab));
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void add(IsWidget w, String text) {
add(asWidgetOrNull(w), text);
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly with a view name.
*/
// Added for Cedar Common
public void add(IsWidget w, String viewName, String text) {
add(w, viewName, text, getWidgetCount() - 1);
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly with a view name and index.
* The tab will be inserted at the desired index, or at the end of the list if that's not possible
* @return the actual index the tab was inserted at
*/
//Added for Cedar Common
public int add(IsWidget w, String viewName, String text, int index) {
if (index > getWidgetCount() - 1) {
index = getWidgetCount() - 1; // if we can't put it where they request, then put it at the end
}
Widget contents = new Label(text);
Tab tab = new Tab(contents);
insert(asWidgetOrNull(w), tab, index + 1);
if (viewName != null) {
if (this.getElementId() != null) {
String elementId = this.getElementId() + "_" + viewName;
tab.setElementId(elementId);
}
}
return index;
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void add(IsWidget w, String text, boolean asHtml) {
add(asWidgetOrNull(w), text, asHtml);
}
@Override
public void add(Widget w) {
insert(w, getWidgetCount());
}
/**
* Adds a widget to the panel. If the Widget is already attached, it will be
* moved to the right-most index.
*
* @param child the widget to be added
* @param text the text to be shown on its tab
*/
public void add(Widget child, String text) {
insert(child, text, getWidgetCount());
}
/**
* Adds a widget to the panel. If the Widget is already attached, it will be
* moved to the right-most index.
*
* @param child the widget to be added
* @param html the html to be shown on its tab
*/
public void add(Widget child, SafeHtml html) {
add(child, html.asString(), true);
}
/**
* Adds a widget to the panel. If the Widget is already attached, it will be
* moved to the right-most index.
*
* @param child the widget to be added
* @param text the text to be shown on its tab
* @param asHtml <code>true</code> to treat the specified text as HTML
*/
public void add(Widget child, String text, boolean asHtml) {
insert(child, text, asHtml, getWidgetCount());
}
/**
* Adds a widget to the panel. If the Widget is already attached, it will be
* moved to the right-most index.
*
* @param child the widget to be added
* @param tab the widget to be placed in the associated tab
*/
public void add(Widget child, Widget tab) {
insert(child, tab, getWidgetCount());
}
@Override
public HandlerRegistration addBeforeSelectionHandler(
BeforeSelectionHandler<Integer> handler) {
return addHandler(handler, BeforeSelectionEvent.getType());
}
@Override
public HandlerRegistration addSelectionHandler(
SelectionHandler<Integer> handler) {
return addHandler(handler, SelectionEvent.getType());
}
@Override
public void animate(int duration) {
animate(duration, null);
}
@Override
public void animate(int duration, AnimationCallback callback) {
deckPanel.animate(duration, callback);
}
@Override
public void clear() {
Iterator<Widget> it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
@Override
public void forceLayout() {
deckPanel.forceLayout();
}
/**
* Get the duration of the animated transition between tabs.
*
* @return the duration in milliseconds
*/
public int getAnimationDuration() {
return deckPanel.getAnimationDuration();
}
/**
* Gets the index of the currently-selected tab.
*
* @return the selected index, or <code>-1</code> if none is selected.
*/
public int getSelectedIndex() {
return selectedIndex;
}
/**
* Gets the widget in the tab at the given index.
*
* @param index the index of the tab to be retrieved
* @return the tab's widget
*/
public Widget getTabWidget(int index) {
checkIndex(index);
return tabs.get(index).getWidget();
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public Widget getTabWidget(IsWidget child) {
return getTabWidget(asWidgetOrNull(child));
}
/**
* Gets the widget in the tab associated with the given child widget.
*
* @param child the child whose tab is to be retrieved
* @return the tab's widget
*/
public Widget getTabWidget(Widget child) {
checkChild(child);
return getTabWidget(getWidgetIndex(child));
}
/**
* Returns the widget at the given index.
*/
@Override
public Widget getWidget(int index) {
return deckPanel.getWidget(index);
}
/** Return the title for the tab with the given index. */
// Added for Cedar Common
public String getTitle(int index) {
if (index < this.tabs.size()) {
Tab tab = this.tabs.get(index);
if (tab.getWidget() instanceof Label) {
return ((Label) tab.getWidget()).getText();
}
}
return null;
}
/** Return the elementId for the tab with the given index. */
// Added for Cedar Common
public String getElementId(int index) {
if (index < this.tabs.size()) {
return this.tabs.get(index).getElementId();
}
return null;
}
/** Deselect all tabs. */
// Added for Cedar Common
public void deselectAllTabs() {
for (int index = 0; index < this.tabs.size(); index++) {
this.tabs.get(index).setSelected(false);
}
}
/**
* Returns the number of tabs and widgets.
*/
@Override
public int getWidgetCount() {
return deckPanel.getWidgetCount();
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
@Override
public int getWidgetIndex(IsWidget child) {
return getWidgetIndex(asWidgetOrNull(child));
}
/**
* Returns the index of the given child, or -1 if it is not a child.
*/
@Override
public int getWidgetIndex(Widget child) {
return deckPanel.getWidgetIndex(child);
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void insert(IsWidget child, int beforeIndex) {
insert(asWidgetOrNull(child), beforeIndex);
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void insert(IsWidget child, IsWidget tab, int beforeIndex) {
insert(asWidgetOrNull(child), asWidgetOrNull(tab), beforeIndex);
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void insert(IsWidget child, String text, boolean asHtml, int beforeIndex) {
insert(asWidgetOrNull(child), text, asHtml, beforeIndex);
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void insert(IsWidget child, String text, int beforeIndex) {
insert(asWidgetOrNull(child), text, beforeIndex);
}
/**
* Inserts a widget into the panel. If the Widget is already attached, it will
* be moved to the requested index.
*
* @param child the widget to be added
* @param beforeIndex the index before which it will be inserted
*/
public void insert(Widget child, int beforeIndex) {
insert(child, "", beforeIndex);
}
/**
* Inserts a widget into the panel. If the Widget is already attached, it will
* be moved to the requested index.
*
* @param child the widget to be added
* @param html the html to be shown on its tab
* @param beforeIndex the index before which it will be inserted
*/
public void insert(Widget child, SafeHtml html, int beforeIndex) {
insert(child, html.asString(), true, beforeIndex);
}
/**
* Inserts a widget into the panel. If the Widget is already attached, it will
* be moved to the requested index.
*
* @param child the widget to be added
* @param text the text to be shown on its tab
* @param asHtml <code>true</code> to treat the specified text as HTML
* @param beforeIndex the index before which it will be inserted
*/
public void insert(Widget child, String text, boolean asHtml, int beforeIndex) {
Widget contents;
if (asHtml) {
contents = new HTML(text);
} else {
contents = new Label(text);
}
insert(child, contents, beforeIndex);
}
/**
* Inserts a widget into the panel. If the Widget is already attached, it will
* be moved to the requested index.
*
* @param child the widget to be added
* @param text the text to be shown on its tab
* @param beforeIndex the index before which it will be inserted
*/
public void insert(Widget child, String text, int beforeIndex) {
insert(child, text, false, beforeIndex);
}
/**
* Inserts a widget into the panel. If the Widget is already attached, it will
* be moved to the requested index.
*
* @param child the widget to be added
* @param tab the widget to be placed in the associated tab
* @param beforeIndex the index before which it will be inserted
*/
public void insert(Widget child, Widget tab, int beforeIndex) {
insert(child, new Tab(tab), beforeIndex);
}
/**
* Check whether or not transitions slide in vertically or horizontally.
* Defaults to horizontally.
*
* @return true for vertical transitions, false for horizontal
*/
public boolean isAnimationVertical() {
return deckPanel.isAnimationVertical();
}
@Override
public Iterator<Widget> iterator() {
return deckPanel.iterator();
}
@Override
public boolean remove(int index) {
if ((index < 0) || (index >= getWidgetCount())) {
return false;
}
Widget child = getWidget(index);
tabBar.remove(index);
deckPanel.removeProtected(child);
child.removeStyleName(CONTENT_STYLE);
Tab tab = tabs.remove(index);
tab.getWidget().removeFromParent();
if (index == selectedIndex) {
// If the selected tab is being removed, select the first tab (if there
// is one).
selectedIndex = -1;
if (getWidgetCount() > 0) {
selectTab(0);
}
} else if (index < selectedIndex) {
// If the selectedIndex is greater than the one being removed, it needs
// to be adjusted.
--selectedIndex;
}
return true;
}
/**
* Remove the tab at the indicated index, without selecting any tab as a result.
* This is intended for use when replacing the view that is rendering a tab.
* The caller MUST re-select a valid tab after calling this method.
*/
// Added for Cedar Common
public boolean removeWithoutSelecting(int index) {
if ((index < 0) || (index >= getWidgetCount())) {
return false;
}
Widget child = getWidget(index);
tabBar.remove(index);
deckPanel.removeProtected(child);
child.removeStyleName(CONTENT_STYLE);
Tab tab = tabs.remove(index);
tab.getWidget().removeFromParent();
selectedIndex = -1; // otherwise, this tab still looks selected, and attempt to re-select it are ignored
return true;
}
@Override
public boolean remove(Widget w) {
int index = getWidgetIndex(w);
if (index == -1) {
return false;
}
return remove(index);
}
/**
* Programmatically selects the specified tab and fires events.
*
* @param index the index of the tab to be selected
*/
public void selectTab(int index) {
selectTab(index, true);
}
/**
* Programmatically selects the specified tab.
*
* @param index the index of the tab to be selected
* @param fireEvents true to fire events, false not to
*/
public void selectTab(int index, boolean fireEvents) {
checkIndex(index);
if (index == selectedIndex) {
return;
}
// Fire the before selection event, giving the recipients a chance to
// cancel the selection.
if (fireEvents) {
BeforeSelectionEvent<Integer> event = BeforeSelectionEvent.fire(this,
index);
if ((event != null) && event.isCanceled()) {
return;
}
}
// Update the tabs being selected and unselected.
if (selectedIndex != -1) {
tabs.get(selectedIndex).setSelected(false);
}
deckPanel.showWidget(index);
tabs.get(index).setSelected(true);
selectedIndex = index;
// Fire the selection event.
if (fireEvents) {
SelectionEvent.fire(this, index);
}
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void selectTab(IsWidget child) {
selectTab(asWidgetOrNull(child));
}
/**
* Convenience overload to allow {@link IsWidget} to be used directly.
*/
public void selectTab(IsWidget child, boolean fireEvents) {
selectTab(asWidgetOrNull(child), fireEvents);
}
/**
* Programmatically selects the specified tab and fires events.
*
* @param child the child whose tab is to be selected
*/
public void selectTab(Widget child) {
selectTab(getWidgetIndex(child));
}
/**
* Programmatically selects the specified tab.
*
* @param child the child whose tab is to be selected
* @param fireEvents true to fire events, false not to
*/
public void selectTab(Widget child, boolean fireEvents) {
selectTab(getWidgetIndex(child), fireEvents);
}
/**
* Set the duration of the animated transition between tabs.
*
* @param duration the duration in milliseconds.
*/
public void setAnimationDuration(int duration) {
deckPanel.setAnimationDuration(duration);
}
/**
* Set whether or not transitions slide in vertically or horizontally.
*
* @param isVertical true for vertical transitions, false for horizontal
*/
public void setAnimationVertical(boolean isVertical) {
deckPanel.setAnimationVertical(isVertical);
}
/**
* Sets a tab's HTML contents.
*
* Use care when setting an object's HTML; it is an easy way to expose
* script-based security problems. Consider using
* {@link #setTabHTML(int, SafeHtml)} or
* {@link #setTabText(int, String)} whenever possible.
*
* @param index the index of the tab whose HTML is to be set
* @param html the tab's new HTML contents
*/
public void setTabHTML(int index, String html) {
checkIndex(index);
tabs.get(index).setWidget(new HTML(html));
}
/**
* Sets a tab's HTML contents.
*
* @param index the index of the tab whose HTML is to be set
* @param html the tab's new HTML contents
*/
public void setTabHTML(int index, SafeHtml html) {
setTabHTML(index, html.asString());
}
/**
* Sets a tab's text contents.
*
* @param index the index of the tab whose text is to be set
* @param text the object's new text
*/
public void setTabText(int index, String text) {
checkIndex(index);
tabs.get(index).setWidget(new Label(text));
}
private void checkChild(Widget child) {
assert getWidgetIndex(child) >= 0 : "Child is not a part of this panel";
}
private void checkIndex(int index) {
assert (index >= 0) && (index < getWidgetCount()) : "Index out of bounds";
}
private void insert(final Widget child, Tab tab, int beforeIndex) {
assert (beforeIndex >= 0) && (beforeIndex <= getWidgetCount()) : "beforeIndex out of bounds";
// Check to see if the TabPanel already contains the Widget. If so,
// remove it and see if we need to shift the position to the left.
int idx = getWidgetIndex(child);
if (idx != -1) {
remove(child);
if (idx < beforeIndex) {
beforeIndex--;
}
}
deckPanel.insertProtected(child, beforeIndex);
tabs.add(beforeIndex, tab);
tabBar.insert(tab, beforeIndex);
tab.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
selectTab(child);
}
});
child.addStyleName(CONTENT_STYLE);
if (selectedIndex == -1) {
selectTab(0);
} else if (selectedIndex >= beforeIndex) {
// If we inserted before the currently selected tab, its index has just
// increased.
selectedIndex++;
}
}
// Added for Cedar Common
public Double getBarHeight() {
return this.barHeight;
}
// Added for Cedar Common
public void setBarHeight(Integer barHeight) {
if (barHeight == null) {
this.setBarHeight((Double) null);
} else {
this.setBarHeight(new Double(barHeight.intValue()));
}
}
// Added for Cedar Common
private void setBarHeight(Double barHeight) {
this.barHeight = barHeight;
configureBar();
}
// Added for Cedar Common
public Unit getBarUnit() {
return this.barUnit;
}
// Added for Cedar Common
public void setBarUnit(String barUnit) {
if (barUnit == null) {
this.setBarUnit((Unit) null);
} else {
this.setBarUnit(Unit.valueOf(barUnit));
}
}
// Added for Cedar Common
private void setBarUnit(Unit barUnit) {
this.barUnit = barUnit;
configureBar();
}
// Added for Cedar Common
private void configureBar() {
if (this.barHeight != null && this.barUnit != null) {
panel.setWidgetLeftRight(tabBar, 0, Unit.PX, 0, Unit.PX);
panel.setWidgetTopHeight(tabBar, 0, Unit.PX, barHeight, barUnit);
panel.setWidgetVerticalPosition(tabBar, Alignment.END);
panel.setWidgetLeftRight(deckPanel, 0, Unit.PX, 0, Unit.PX);
panel.setWidgetTopBottom(deckPanel, barHeight, barUnit, 0, Unit.PX);
}
}
// Added for Cedar Common
@Override
public void setElementId(String elementId) {
this.getElement().setId(elementId);
}
// Added for Cedar Common
@Override
public String getElementId() {
return this.getElement().getId();
}
}