/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
/*
* Created 07.02.2003 16:00:00.
* $Id: TabGroupRenderer.java 1368577 2012-08-02 16:20:31Z lofwyr $
*/
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.tobago.TobagoConstants;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_HEIGHT;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_IMAGE;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LAYOUT_HEIGHT;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LAYOUT_WIDTH;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_ONCLICK;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_SELECTED_INDEX;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_BODY;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_CLASS;
import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_HEADER;
import org.apache.myfaces.tobago.ajax.api.AjaxRenderer;
import org.apache.myfaces.tobago.ajax.api.AjaxUtils;
import org.apache.myfaces.tobago.component.ComponentUtil;
import org.apache.myfaces.tobago.component.UICommand;
import org.apache.myfaces.tobago.component.UIPage;
import org.apache.myfaces.tobago.component.UIPanelBase;
import org.apache.myfaces.tobago.component.UITab;
import org.apache.myfaces.tobago.component.UITabGroup;
import static org.apache.myfaces.tobago.component.UITabGroup.SWITCH_TYPE_CLIENT;
import static org.apache.myfaces.tobago.component.UITabGroup.SWITCH_TYPE_RELOAD_TAB;
import org.apache.myfaces.tobago.component.UIToolBar;
import org.apache.myfaces.tobago.config.TobagoConfig;
import org.apache.myfaces.tobago.context.ResourceManagerUtil;
import org.apache.myfaces.tobago.event.TabChangeEvent;
import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
import org.apache.myfaces.tobago.renderkit.LayoutInformationProvider;
import org.apache.myfaces.tobago.renderkit.LayoutableRendererBase;
import org.apache.myfaces.tobago.renderkit.RenderUtil;
import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlConstants;
import org.apache.myfaces.tobago.renderkit.html.HtmlRendererUtil;
import org.apache.myfaces.tobago.renderkit.html.HtmlStyleMap;
import org.apache.myfaces.tobago.renderkit.html.StyleClasses;
import org.apache.myfaces.tobago.util.AccessKeyMap;
import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.component.UIPanel;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class TabGroupRenderer extends LayoutableRendererBase implements AjaxRenderer {
private static final Log LOG = LogFactory.getLog(TabGroupRenderer.class);
private static final String[] SCRIPTS = new String[]{"script/tab.js", "script/tabgroup.js", "script/tobago-menu.js"};
public static final String ACTIVE_INDEX_POSTFIX = "__activeIndex";
public void decode(FacesContext facesContext, UIComponent component) {
if (ComponentUtil.isOutputOnly(component)) {
return;
}
int oldIndex = ((UITabGroup) component).getRenderedIndex();
String clientId = component.getClientId(facesContext);
final Map parameters = facesContext.getExternalContext().getRequestParameterMap();
String newValue = (String) parameters.get(clientId + ACTIVE_INDEX_POSTFIX);
try {
int activeIndex = Integer.parseInt(newValue);
if (activeIndex != oldIndex) {
TabChangeEvent event = new TabChangeEvent(component, oldIndex, activeIndex);
component.queueEvent(event);
}
} catch (NumberFormatException e) {
LOG.error("Can't parse activeIndex: '" + newValue + "'");
}
//HtmlRendererUtil.createHeaderAndBodyStyles(facesContext, component);
}
public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException {
UITabGroup component = (UITabGroup) uiComponent;
HtmlRendererUtil.createHeaderAndBodyStyles(facesContext, component);
layoutTabs(facesContext, component);
int activeIndex = ensureRenderedActiveIndex(facesContext, component);
final String clientId = component.getClientId(facesContext);
final String hiddenId = clientId + TabGroupRenderer.ACTIVE_INDEX_POSTFIX;
final String switchType = component.getSwitchType();
UIPage page = ComponentUtil.findPage(facesContext, component);
page.getScriptFiles().addAll(Arrays.asList(SCRIPTS));
if (TobagoConfig.getInstance(facesContext).isAjaxEnabled()) {
HtmlRendererUtil.writeScriptLoader(facesContext, SCRIPTS, new String[0]);
}
TobagoResponseWriter writer = HtmlRendererUtil.getTobagoResponseWriter(facesContext);
writer.startElement(HtmlConstants.INPUT, null);
writer.writeAttribute(HtmlAttributes.TYPE, "hidden", false);
writer.writeAttribute(HtmlAttributes.VALUE, Integer.toString(activeIndex), false);
writer.writeNameAttribute(hiddenId);
writer.writeIdAttribute(hiddenId);
writer.endElement(HtmlConstants.INPUT);
String image1x1 = ResourceManagerUtil.getImageWithPath(facesContext, "image/1x1.gif");
TabList tabList = getTabList(facesContext, component);
// if a outer uiPage is presend, the virtual tab will go over all
// tabs and render it as they are selected, and it will
// selected with stylesheet.
int virtualTab = 0;
int currentWidth = 0;
int navigationBarWidth = 0;
if (ComponentUtil.getBooleanAttribute(component, TobagoConstants.ATTR_SHOW_NAVIGATION_BAR)) {
navigationBarWidth = getConfiguredValue(facesContext, component, "navigationBarWidth");
}
for (UIComponent tab : (List<UIComponent>) component.getChildren()) {
if (tab instanceof UIPanelBase) {
if (tab.isRendered()) {
currentWidth += tabList.getWidthList().get(virtualTab);
if (SWITCH_TYPE_CLIENT.equals(switchType) || virtualTab == activeIndex) {
if (virtualTab != activeIndex) {
HtmlRendererUtil.replaceStyleAttribute(component, "display", "none");
} else {
HtmlRendererUtil.removeStyleAttribute(component, "display");
}
writer.startElement(HtmlConstants.DIV, null);
writer.writeComment("empty div fix problem with mozilla and fieldset");
writer.endElement(HtmlConstants.DIV);
writer.startElement(HtmlConstants.DIV, null);
writer.writeIdAttribute(clientId);
StyleClasses classes = (StyleClasses) component.getAttributes().get(ATTR_STYLE_CLASS);
writer.writeClassAttribute(classes);
renderTabGroupView(facesContext, writer, component, virtualTab,
(HtmlStyleMap) component.getAttributes().get(ATTR_STYLE),
switchType, image1x1, navigationBarWidth, currentWidth, tabList);
writer.endElement(HtmlConstants.DIV);
if (TobagoConfig.getInstance(facesContext).isAjaxEnabled()
&& SWITCH_TYPE_RELOAD_TAB.equals(switchType)) {
final String[] cmds = {
"new Tobago.TabGroup(",
" '" + clientId + "', ",
" '" + activeIndex + "', ",
" '" + component.getChildCount() + "');"
};
HtmlRendererUtil.writeScriptLoader(facesContext, new String[0], cmds);
}
}
}
virtualTab++;
}
}
}
private Integer getCurrentWidth(TabList tabs, int tabIndex) {
int currentWidth = 0;
for (int i = 0; i <= tabIndex; i++) {
currentWidth += tabs.getWidthList().get(i);
}
return currentWidth;
}
private TabList getTabList(FacesContext facesContext, UITabGroup component) {
TabList tabs = new TabList();
int index = 0;
int tabLabelExtraWidth = getConfiguredValue(facesContext, component, "tabLabelExtraWidth");
boolean first = true;
for (UIComponent child : (List<UIComponent>) component.getChildren()) {
if (child instanceof UITab) {
UITab tab = (UITab) child;
if (tab.isRendered()) {
LabelWithAccessKey label = new LabelWithAccessKey(tab);
if (label.getText() != null) {
tabs.getWidthList().add(RenderUtil.calculateStringWidth2(facesContext, component, label.getText())
+ tabLabelExtraWidth);
} else {
tabs.getWidthList().add(RenderUtil.calculateStringWidth2(facesContext,
component, Integer.toString(index + 1)) + tabLabelExtraWidth);
}
if (first) {
tabs.firstIndex = index;
first = false;
}
tabs.lastIndex = index;
} else {
tabs.getWidthList().add(0);
}
index++;
}
}
return tabs;
}
private int ensureRenderedActiveIndex(FacesContext context, UITabGroup tabGroup) {
int activeIndex = tabGroup.getSelectedIndex();
// ensure to select a rendered tab
int index = -1;
int closestRenderedTabIndex = -1;
for (UIComponent tab : (List<UIComponent>) tabGroup.getChildren()) {
index++;
if (tab instanceof UIPanelBase) {
if (index == activeIndex) {
if (tab.isRendered()) {
return index;
} else if (closestRenderedTabIndex > -1) {
break;
}
}
if (tab.isRendered()) {
closestRenderedTabIndex = index;
if (index > activeIndex) {
break;
}
}
}
}
if (closestRenderedTabIndex == -1) {
// resetting index to 0
closestRenderedTabIndex = 0;
}
ValueBinding vb = tabGroup.getValueBinding(ATTR_SELECTED_INDEX);
if (vb != null) {
vb.setValue(context, closestRenderedTabIndex);
} else {
tabGroup.setSelectedIndex(closestRenderedTabIndex);
}
return closestRenderedTabIndex;
}
private void renderTabGroupView(FacesContext facesContext, TobagoResponseWriter writer, UITabGroup component,
int virtualTab, HtmlStyleMap oStyle, String switchType, String image1x1, int toolbarWidth,
int currentWidth, TabList tabList) throws IOException {
writer.startElement(HtmlConstants.TABLE, null);
writer.writeAttribute(HtmlAttributes.BORDER, 0);
writer.writeAttribute(HtmlAttributes.CELLPADDING, 0);
writer.writeAttribute(HtmlAttributes.CELLSPACING, 0);
writer.writeAttribute(HtmlAttributes.SUMMARY, "", false);
final String clientId = component.getClientId(facesContext);
writer.writeIdAttribute(clientId + "__" + virtualTab);
writer.writeStyleAttribute(oStyle);
writer.startElement(HtmlConstants.TR, null);
writer.writeAttribute(HtmlAttributes.VALIGN, "bottom", false);
writer.startElement(HtmlConstants.TD, null);
HtmlStyleMap headerStyle = (HtmlStyleMap) component.getAttributes().get(ATTR_STYLE_HEADER);
headerStyle.put("position", "relative");
headerStyle.put("width", headerStyle.getInt("width"));
int width = headerStyle.getInt("width");
writer.writeStyleAttribute(headerStyle);
writer.startElement(HtmlConstants.DIV, null);
writer.writeStyleAttribute(headerStyle);
writer.startElement(HtmlConstants.DIV, null);
HtmlStyleMap map = new HtmlStyleMap();
if (currentWidth > width) {
map.put("width", currentWidth);
map.put("left", width - toolbarWidth - currentWidth);
} else {
map.put("width", width - toolbarWidth);
}
map.put("overflow", "hidden");
map.put("position", "absolute");
writer.writeStyleAttribute(map);
writer.startElement(HtmlConstants.TABLE, component);
writer.writeAttribute(HtmlAttributes.BORDER, 0);
writer.writeAttribute(HtmlAttributes.CELLPADDING, 0);
writer.writeAttribute(HtmlAttributes.CELLSPACING, 0);
writer.writeAttribute(HtmlAttributes.SUMMARY, "", false);
headerStyle = (HtmlStyleMap) component.getAttributes().get(ATTR_STYLE_HEADER);
writer.writeStyleAttribute(headerStyle);
writer.startElement(HtmlConstants.COLGROUP, null);
for (Integer colWidth : tabList.getWidthList()) {
// skip col with width zero
if (colWidth > 0) {
writer.startElement(HtmlConstants.COL, null);
writer.writeAttribute(HtmlAttributes.WIDTH, colWidth);
writer.endElement(HtmlConstants.COL);
}
}
writer.endElement(HtmlConstants.COLGROUP);
writer.startElement(HtmlConstants.TR, null);
writer.writeAttribute(HtmlAttributes.VALIGN, "bottom", false);
UIToolBar toolBar = null;
if (toolbarWidth > 0) {
toolBar = createToolBar(facesContext, component, virtualTab, switchType, tabList, clientId);
}
UITab activeTab = null;
int index = 0;
for (UIComponent child : (List<UIComponent>) component.getChildren()) {
if (child instanceof UITab) {
UITab tab = (UITab) child;
if (tab.isRendered()) {
String onclick;
if (TobagoConfig.getInstance(facesContext).isAjaxEnabled()
&& SWITCH_TYPE_RELOAD_TAB.equals(switchType)) {
onclick = null;
} else {
onclick = "tobago_switchTab('"+ switchType + "','" + clientId + "'," + index + ','
+ component.getChildCount() + ')';
}
LabelWithAccessKey label = new LabelWithAccessKey(tab);
StyleClasses outerClass = new StyleClasses();
StyleClasses innerClass = new StyleClasses();
if (virtualTab == index) {
outerClass.addClass("tab", "selected-outer");
innerClass.addClass("tab", "selected-inner");
activeTab = (UITab) tab;
} else {
outerClass.addClass("tab", "unselected-outer");
innerClass.addClass("tab", "unselected-inner");
}
outerClass.addMarkupClass(tab, "tab", "outer");
innerClass.addMarkupClass(tab, "tab", "outer");
writer.startElement(HtmlConstants.TD, tab);
map = new HtmlStyleMap();
map.put("width", tabList.getWidthList().get(index));
writer.writeStyleAttribute(map);
writer.writeIdAttribute(tab.getClientId(facesContext));
HtmlRendererUtil.renderTip(tab, writer);
writer.startElement(HtmlConstants.DIV, null);
writer.writeStyleAttribute(map);
writer.startElement(HtmlConstants.DIV, null);
writer.writeClassAttribute(outerClass);
//writer.writeStyleAttribute(map);
writer.startElement(HtmlConstants.DIV, null);
//writer.writeStyleAttribute(map);
writer.writeClassAttribute(innerClass);
writer.startElement(HtmlConstants.SPAN, null);
String tabId = clientId + "__" + virtualTab + "__" + index;
writer.writeIdAttribute(tabId);
if (tab.isDisabled()) {
writer.writeClassAttribute("tobago-tab-disabled");
} else {
writer.writeClassAttribute("tobago-tab-link");
if (onclick != null) {
writer.writeAttribute(HtmlAttributes.ONCLICK, onclick, true);
}
}
if (label.getText() != null) {
HtmlRendererUtil.writeLabelWithAccessKey(writer, label);
} else {
writer.writeText(Integer.toString(index + 1));
}
writer.endElement(HtmlConstants.SPAN);
if (label.getAccessKey() != null) {
if (LOG.isWarnEnabled()
&& !AccessKeyMap.addAccessKey(facesContext, label.getAccessKey())) {
LOG.warn("dublicated accessKey : " + label.getAccessKey());
}
HtmlRendererUtil.addClickAcceleratorKey(
facesContext, tabId, label.getAccessKey());
}
writer.endElement(HtmlConstants.DIV);
writer.endElement(HtmlConstants.DIV);
writer.endElement(HtmlConstants.DIV);
writer.endElement(HtmlConstants.TD);
// tool bar
/*UIMenuCommand menuItem = (UIMenuCommand) application.createComponent(UIMenuCommand.COMPONENT_TYPE);
menuItem.setId(component.getId() + "__" + virtualTab + "__" + index + "__" + "menu");
menuItem.setRendererType("MenuCommand");
if (onclick != null) {
menuItem.getAttributes().put(ATTR_ONCLICK, onclick);
} else {
menuItem.getAttributes().put(ATTR_ONCLICK, "javascript:false");
}
Object label2 = tab.getAttributes().get(ATTR_LABEL);
if (label2 != null) {
menuItem.getAttributes().put(ATTR_LABEL, label2);
}
menu.getChildren().add(menuItem);*/
}
}
index++;
}
//TODO
//writer.startElement(HtmlConstants.TD, null);
//writer.writeAttribute(HtmlAttributes.WIDTH, "100%", false);
writer.startElement(HtmlConstants.TD, null);
if (currentWidth > width) {
writer.writeAttribute(HtmlAttributes.WIDTH, toolbarWidth);
} else {
writer.writeAttribute(HtmlAttributes.WIDTH, Integer.toString((width - currentWidth)) + "px", false);
}
writer.startElement(HtmlConstants.DIV, null);
writer.writeClassAttribute("tobago-tab-fulfill");
writer.startElement(HtmlConstants.IMG, null);
writer.writeAttribute(HtmlAttributes.SRC, image1x1, false);
writer.writeAttribute(HtmlAttributes.ALT, "", false);
writer.endElement(HtmlConstants.IMG);
writer.endElement(HtmlConstants.DIV);
writer.endElement(HtmlConstants.TD);
writer.endElement(HtmlConstants.TR);
writer.endElement(HtmlConstants.TABLE);
writer.endElement(HtmlConstants.DIV);
if (toolBar != null) { // todo: configurable later
renderToolbar(facesContext, writer, toolBar, width - toolbarWidth, toolbarWidth);
}
writer.endElement(HtmlConstants.DIV);
writer.endElement(HtmlConstants.TD);
writer.endElement(HtmlConstants.TR);
encodeContent(writer, facesContext, activeTab);
writer.endElement(HtmlConstants.TABLE);
}
private UIToolBar createToolBar(FacesContext facesContext, UITabGroup component, int virtualTab, String switchType,
TabGroupRenderer.TabList tabList, String clientId) {
Application application = facesContext.getApplication();
// tool bar
UICommand scrollLeft = (UICommand) application.createComponent(UICommand.COMPONENT_TYPE);
scrollLeft.setId(component.getId() + "__" + virtualTab + "__" + "previous");
//scrollLeft.setId(facesContext.getViewRoot().createUniqueId());
scrollLeft.setRendererType(null);
scrollLeft.getAttributes().put(ATTR_IMAGE, "image/tabPrev.gif");
if (tabList.isFirst(virtualTab)) {
scrollLeft.setDisabled(true);
}
if (!(TobagoConfig.getInstance(facesContext).isAjaxEnabled() && SWITCH_TYPE_RELOAD_TAB.equals(switchType))) {
scrollLeft.getAttributes().put(ATTR_ONCLICK, "tobago_previousTab('" + switchType + "','" + clientId + "',"
+ component.getChildCount() + ')');
} else {
scrollLeft.getAttributes().put(ATTR_ONCLICK, "javascript:false");
}
UICommand scrollRight = (UICommand) application.createComponent(UICommand.COMPONENT_TYPE);
scrollRight.setId(component.getId() + "__" + virtualTab + "__" + "next");
scrollRight.setRendererType(null);
scrollRight.getAttributes().put(ATTR_IMAGE, "image/tabNext.gif");
if (tabList.isLast(virtualTab)) {
scrollRight.setDisabled(true);
}
if (!(TobagoConfig.getInstance(facesContext).isAjaxEnabled() && SWITCH_TYPE_RELOAD_TAB.equals(switchType))) {
scrollRight.getAttributes().put(ATTR_ONCLICK, "tobago_nextTab('" + switchType + "','" + clientId + "',"
+ component.getChildCount() + ')');
} else {
scrollRight.getAttributes().put(ATTR_ONCLICK, "javascript:false");
}
/*UICommand commandList = (UICommand) application.createComponent(UICommand.COMPONENT_TYPE);
commandList.setId(component.getId() + "__commandList);
commandList.setRendererType(null);
UIMenu menu = (UIMenu) application.createComponent(UIMenu.COMPONENT_TYPE);
menu.setId(component.getId() + "__" + virtualTab + "__" + "menu");
menu.setRendererType(null);
commandList.getFacets().put(FACET_MENUPOPUP, menu);*/
UIToolBar toolBar = (UIToolBar) application.createComponent(UIToolBar.COMPONENT_TYPE);
toolBar.setId(component.getId() + "__toolBar");
//toolBar.setLabelPosition(UIToolBar.LABEL_OFF);
toolBar.setRendererType("TabNavigationBar");
toolBar.setTransient(true);
//toolBar.setIconSize(AbstractUIToolBar.ICON_OFF);
toolBar.getChildren().add(scrollLeft);
toolBar.getChildren().add(scrollRight);
//toolBar.getChildren().add(commandList);
component.getFacets().put(TobagoConstants.FACET_TOOL_BAR, toolBar);
return toolBar;
}
private void renderToolbar(FacesContext facesContext, TobagoResponseWriter writer, UIPanel toolbar, int width,
int navigationBarWidth) throws IOException {
writer.startElement(HtmlConstants.DIV, null);
HtmlStyleMap map = new HtmlStyleMap();
map.put("width", navigationBarWidth);
map.put("left", width);
writer.writeStyleAttribute(map);
writer.writeClassAttribute("tobago-tabNavigationBar");
RenderUtil.encode(facesContext, toolbar);
writer.endElement(HtmlConstants.DIV);
}
protected void encodeContent(TobagoResponseWriter writer, FacesContext facesContext, UITab activeTab)
throws IOException {
HtmlStyleMap bodyStyle = (HtmlStyleMap)
activeTab.getParent().getAttributes().get(ATTR_STYLE_BODY);
writer.startElement(HtmlConstants.TR, null);
writer.startElement(HtmlConstants.TD, null);
StyleClasses classes = new StyleClasses();
classes.addClass("tab", "content");
classes.addMarkupClass(activeTab, "tab", "content");
writer.writeClassAttribute(classes);
writer.writeStyleAttribute(bodyStyle);
writer.flush();
RenderUtil.encodeChildren(facesContext, activeTab);
writer.endElement(HtmlConstants.TD);
writer.endElement(HtmlConstants.TR);
}
public void encodeAjax(FacesContext context, UIComponent component) throws IOException {
AjaxUtils.checkParamValidity(context, component, UITabGroup.class);
TabList tabList = getTabList(context, (UITabGroup) component);
int index = ensureRenderedActiveIndex(context, (UITabGroup) component);
int currentWidth = getCurrentWidth(tabList, index);
int navigationBarWidth = 0;
if (ComponentUtil.getBooleanAttribute(component, TobagoConstants.ATTR_SHOW_NAVIGATION_BAR)) {
navigationBarWidth = getConfiguredValue(context, component, "navigationBarWidth");
}
renderTabGroupView(context, HtmlRendererUtil.getTobagoResponseWriter(context),
(UITabGroup) component, index,
(HtmlStyleMap) component.getAttributes().get(ATTR_STYLE), SWITCH_TYPE_RELOAD_TAB,
ResourceManagerUtil.getImageWithPath(context, "image/1x1.gif"),
navigationBarWidth, currentWidth, tabList);
}
public int getFixedHeight(FacesContext facesContext, UIComponent uiComponent) {
UITabGroup component = (UITabGroup) uiComponent;
int height =
ComponentUtil.getIntAttribute(component, ATTR_HEIGHT, -1);
int fixedHeight;
if (height != -1) {
fixedHeight = height;
} else {
fixedHeight = 0;
for (UIComponent tab : (List<UIComponent>) component.getChildren()) {
if (tab instanceof UIPanelBase && tab.isRendered()) {
LayoutInformationProvider renderer = ComponentUtil.getRenderer(facesContext, tab);
fixedHeight
= Math.max(fixedHeight, renderer.getFixedHeight(facesContext, tab));
}
}
fixedHeight += getConfiguredValue(facesContext, component, "headerHeight");
fixedHeight += getConfiguredValue(facesContext, component, "paddingHeight");
}
return fixedHeight;
}
private void layoutTabs(FacesContext facesContext, UITabGroup component) {
Object layoutWidth =
component.getAttributes().get(ATTR_LAYOUT_WIDTH);
Object layoutHeight =
component.getAttributes().get(ATTR_LAYOUT_HEIGHT);
for (UIComponent tab : (List<UIComponent>) component.getChildren()) {
if (tab instanceof UIPanelBase && tab.isRendered()) {
if (layoutWidth != null) {
HtmlRendererUtil.layoutSpace(facesContext, tab, true);
}
if (layoutHeight != null) {
HtmlRendererUtil.layoutSpace(facesContext, tab, false);
}
}
}
}
private static class TabList {
private List<Integer> widthList = new ArrayList<Integer>();
private int firstIndex;
private int lastIndex;
public List<Integer> getWidthList() {
return widthList;
}
public boolean isFirst(int index) {
return firstIndex == index;
}
public boolean isLast(int index) {
return lastIndex == index;
}
}
}