001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client.ui; 029 030import org.opencms.gwt.client.I_CmsDescendantResizeHandler; 031import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 032import org.opencms.gwt.client.util.CmsDomUtil; 033import org.opencms.util.CmsStringUtil; 034 035import java.util.HashMap; 036import java.util.Iterator; 037import java.util.List; 038import java.util.Map; 039import java.util.Map.Entry; 040 041import com.google.gwt.core.client.Scheduler; 042import com.google.gwt.core.client.Scheduler.ScheduledCommand; 043import com.google.gwt.dom.client.Element; 044import com.google.gwt.dom.client.Style.Overflow; 045import com.google.gwt.dom.client.Style.Unit; 046import com.google.gwt.event.logical.shared.AttachEvent; 047import com.google.gwt.event.logical.shared.BeforeSelectionHandler; 048import com.google.gwt.event.logical.shared.SelectionHandler; 049import com.google.gwt.event.shared.HandlerRegistration; 050import com.google.gwt.user.client.ui.Composite; 051import com.google.gwt.user.client.ui.DeckLayoutPanel; 052import com.google.gwt.user.client.ui.FlowPanel; 053import com.google.gwt.user.client.ui.LayoutPanel; 054import com.google.gwt.user.client.ui.TabLayoutPanel; 055import com.google.gwt.user.client.ui.Widget; 056 057/** 058 * Wrapper class for @see com.google.user.client.ui.TabLayoutPanel.<p> 059 * 060 * Layout class for a panel with several tabs. The tabbed panel should be set inside a widget with given width and height. 061 * For table based layouts the height of the parent cell should be set explicitly. 062 * 063 * As layout options two height for the tabbar are provided: 32px("standard") and 25px("small"). 064 * 065 * @param <E> the tab widget type 066 * 067 * @since 8.0.0 068 * 069 */ 070public class CmsTabbedPanel<E extends Widget> extends Composite implements I_CmsDescendantResizeHandler, Iterable<E> { 071 072 /** Enumeration with layout keys. */ 073 public enum CmsTabbedPanelStyle { 074 075 /** Button style. */ 076 buttonTabs(30, I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().buttonTabs(), 077 I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().black()), 078 079 /** Classic style. */ 080 classicTabs(28, I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().classicTabs(), null); 081 082 /** The default tabbar height. */ 083 public static final CmsTabbedPanelStyle DEFAULT = buttonTabs; 084 085 /** Property name. */ 086 private int m_barHeight; 087 088 /** The general panel style name. */ 089 private String m_styleClass; 090 091 /** The tab color style name. */ 092 private String m_tabColorClass; 093 094 /** 095 * Constructor.<p> 096 * 097 * @param barHeight the height of the bar 098 * @param styleClass the tab style class 099 * @param tabColorClass the tab color 100 */ 101 private CmsTabbedPanelStyle(int barHeight, String styleClass, String tabColorClass) { 102 103 m_barHeight = barHeight; 104 m_styleClass = styleClass; 105 m_tabColorClass = tabColorClass; 106 } 107 108 /** 109 * Returns the barHeight.<p> 110 * 111 * @return the barHeight 112 */ 113 public int getBarHeight() { 114 115 return m_barHeight; 116 } 117 118 /** 119 * Returns the styleClass.<p> 120 * 121 * @return the styleClass 122 */ 123 public String getStyleClass() { 124 125 return m_styleClass; 126 } 127 128 /** 129 * Returns the tabColorClass.<p> 130 * 131 * @return the tabColorClass 132 */ 133 public String getTabColorClass() { 134 135 return m_tabColorClass; 136 } 137 } 138 139 /** 140 * Extending the TabLayoutPanel class to allow height adjustments to the tab bar.<p> 141 */ 142 protected class TabPanel extends TabLayoutPanel { 143 144 /** The tab content panel. */ 145 private DeckLayoutPanel m_contentPanel; 146 147 /** The tab bar. */ 148 private FlowPanel m_tabBar; 149 150 /** 151 * Constructor.<p> 152 * 153 * @param barHeight the tab bar height 154 * @param barUnit the height unit 155 */ 156 public TabPanel(double barHeight, Unit barUnit) { 157 158 super(barHeight, barUnit); 159 LayoutPanel tabLayout = (LayoutPanel)getWidget(); 160 // Find the tab bar, which is the first flow panel in the LayoutPanel 161 for (int i = 0; i < tabLayout.getWidgetCount(); ++i) { 162 Widget widget = tabLayout.getWidget(i); 163 if (widget instanceof FlowPanel) { 164 m_tabBar = (FlowPanel)widget; 165 break; // tab bar found 166 } 167 } 168 169 for (int i = 0; i < tabLayout.getWidgetCount(); ++i) { 170 Widget widget = tabLayout.getWidget(i); 171 if (widget instanceof DeckLayoutPanel) { 172 m_contentPanel = (DeckLayoutPanel)widget; 173 break; // tab bar found 174 } 175 } 176 } 177 178 /** 179 * Checks the tab bar for necessary height adjustments.<p> 180 */ 181 protected void checkTabOverflow() { 182 183 int height = m_tabBar.getOffsetHeight(); 184 m_contentPanel.getElement().getParentElement().getStyle().setTop(height, Unit.PX); 185 } 186 } 187 188 /** The TabLayoutPanel widget. */ 189 TabPanel m_tabPanel; 190 191 /** Auto resize mode. */ 192 private boolean m_autoResize; 193 194 /** Offset which is added to the measured tab content height to resize the panel. */ 195 private int m_autoResizeHeightDelta; 196 197 /** Stores the indexes and the title of disabled tabs. */ 198 private Map<Integer, String> m_disabledTabIndexes = new HashMap<Integer, String>(); 199 200 /** The tab panel style. */ 201 private CmsTabbedPanelStyle m_panelStyle; 202 203 /** A map from ids to tabs. */ 204 private Map<String, E> m_tabsById = new HashMap<String, E>(); 205 206 /** 207 * The default constructor for an empty tabbed panel. <p> 208 */ 209 public CmsTabbedPanel() { 210 211 this(CmsTabbedPanelStyle.DEFAULT); 212 } 213 214 /** 215 * The constructor for an empty tabbed panel. <p> 216 * 217 * @param tabbedPanelStyle the pre-defined height of the tabbar, can be "small" or "standard" 218 */ 219 public CmsTabbedPanel(CmsTabbedPanelStyle tabbedPanelStyle) { 220 221 m_tabPanel = new TabPanel(tabbedPanelStyle.getBarHeight(), Unit.PX); 222 m_panelStyle = tabbedPanelStyle; 223 224 // All composites must call initWidget() in their constructors. 225 initWidget(m_tabPanel); 226 227 Element tabRootEl = m_tabPanel.getElement(); 228 // set an additional css class for the parent element of the .gwt-TabLayoutPanelTabs element 229 List<Element> tabBarDivs = CmsDomUtil.getElementsByClass( 230 I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cmsTabLayoutPanelTabs(), 231 CmsDomUtil.Tag.div, 232 tabRootEl); 233 if (tabBarDivs.size() == 1) { 234 tabBarDivs.get(0).getParentElement().setClassName( 235 I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cmsTabLayoutPanelTabBar() 236 + " " 237 + I_CmsLayoutBundle.INSTANCE.generalCss().cornerTop()); 238 if (m_panelStyle.getTabColorClass() != null) { 239 tabBarDivs.get(0).getParentElement().addClassName(m_panelStyle.getTabColorClass()); 240 } 241 } 242 243 m_tabPanel.setStyleName(m_panelStyle.getStyleClass()); 244 m_tabPanel.addStyleName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cmsTabLayoutPanel()); 245 m_tabPanel.addStyleName( 246 I_CmsLayoutBundle.INSTANCE.generalCss().cornerAll() 247 + " " 248 + I_CmsLayoutBundle.INSTANCE.generalCss().textMedium()); 249 250 m_tabPanel.addAttachHandler(new AttachEvent.Handler() { 251 252 /** 253 * @see com.google.gwt.event.logical.shared.AttachEvent.Handler#onAttachOrDetach(com.google.gwt.event.logical.shared.AttachEvent) 254 */ 255 public void onAttachOrDetach(AttachEvent event) { 256 257 setOverflowVisibleToContent(); 258 Scheduler.get().scheduleDeferred(new ScheduledCommand() { 259 260 public void execute() { 261 262 m_tabPanel.checkTabOverflow(); 263 } 264 }); 265 } 266 }); 267 } 268 269 /** 270 * Add a new tab with the provided name and content.<p> 271 * 272 * Wrapper function for {@link com.google.gwt.user.client.ui.TabLayoutPanel#add(Widget, String)} 273 * 274 * @param tabContent the widget to add as a tab 275 * @param tabName the name of the tab to display in the tabbar 276 */ 277 public void add(E tabContent, String tabName) { 278 279 tabContent.addStyleName(I_CmsLayoutBundle.INSTANCE.generalCss().cornerAll()); 280 m_tabPanel.add(tabContent, CmsDomUtil.stripHtml(tabName)); 281 282 Element tabRootEl = m_tabPanel.getElement(); 283 // set an additional css class for the parent element of the .gwt-TabLayoutPanelTabs element 284 List<Element> tabDivs = CmsDomUtil.getElementsByClass( 285 I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cmsTabLayoutPanelTab(), 286 CmsDomUtil.Tag.div, 287 tabRootEl); 288 289 Iterator<Element> it = tabDivs.iterator(); 290 boolean first = true; 291 while (it.hasNext()) { 292 293 Element e = it.next(); 294 e.removeClassName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cornerLeft()); 295 e.removeClassName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cornerRight()); 296 if (first) { 297 e.addClassName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cornerLeft()); 298 first = false; 299 } 300 if (!it.hasNext()) { 301 e.addClassName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cornerRight()); 302 } 303 } 304 m_tabPanel.checkTabOverflow(); 305 } 306 307 /** 308 * Add the before selection handler to the tabbed panel.<p> 309 * 310 * Wrapper function for {@link com.google.gwt.user.client.ui.TabLayoutPanel#addBeforeSelectionHandler(BeforeSelectionHandler)} 311 * 312 * @param handler the before selection handler 313 * @return the registration for the event 314 */ 315 public HandlerRegistration addBeforeSelectionHandler(BeforeSelectionHandler<Integer> handler) { 316 317 return m_tabPanel.addBeforeSelectionHandler(handler); 318 } 319 320 /** 321 * Adds a tab with a user-defined id.<p> 322 * 323 * @param tabContent the tab content 324 * @param tabName the tab name 325 * @param tabId the tab id 326 */ 327 public void addNamed(E tabContent, String tabName, String tabId) { 328 329 add(tabContent, tabName); 330 m_tabsById.put(tabId, tabContent); 331 } 332 333 /** 334 * Adds a SelectionEvent handler to the tabbed panel.<p> 335 * 336 * Wrapper function for {@link com.google.gwt.user.client.ui.TabLayoutPanel#addSelectionHandler(SelectionHandler)} 337 * 338 * @param handler the selection handler 339 * @return the registration for the event 340 */ 341 public HandlerRegistration addSelectionHandler(SelectionHandler<Integer> handler) { 342 343 return m_tabPanel.addSelectionHandler(handler); 344 } 345 346 /** 347 * Add a new tab with the provided name and content and additional left margin.<p> 348 * 349 * @param tabContent the widget to add as a tab 350 * @param tabName the name of the tab to display in the tabbar 351 */ 352 public void addWithLeftMargin(E tabContent, String tabName) { 353 354 tabContent.addStyleName(I_CmsLayoutBundle.INSTANCE.generalCss().cornerAll()); 355 m_tabPanel.add(tabContent, CmsDomUtil.stripHtml(tabName)); 356 357 int tabIndex = m_tabPanel.getWidgetIndex(tabContent); 358 Element tabElement = getTabElement(tabIndex); 359 if (tabElement != null) { 360 tabElement.addClassName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().tabLeftMargin()); 361 if (!m_panelStyle.equals(CmsTabbedPanelStyle.classicTabs)) { 362 tabElement.addClassName(I_CmsLayoutBundle.INSTANCE.generalCss().buttonCornerAll()); 363 tabElement.addClassName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().borderAll()); 364 } 365 } 366 m_tabPanel.checkTabOverflow(); 367 } 368 369 /** 370 * Disables the tab with the given index.<p> 371 * 372 * @param tabContent the content of the tab that should be disabled 373 * @param reason the reason why the tab is disabled 374 */ 375 public void disableTab(E tabContent, String reason) { 376 377 Integer index = new Integer(m_tabPanel.getWidgetIndex(tabContent)); 378 Element tab = getTabElement(index.intValue()); 379 if ((tab != null) && !m_disabledTabIndexes.containsKey(index)) { 380 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(tab.getTitle())) { 381 m_disabledTabIndexes.put(index, tab.getTitle()); 382 } else { 383 m_disabledTabIndexes.put(index, ""); 384 } 385 tab.addClassName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().tabDisabled()); 386 tab.setTitle(reason); 387 } 388 } 389 390 /** 391 * Enables the tab with the given index.<p> 392 * 393 * @param tabContent the content of the tab that should be enabled 394 */ 395 public void enableTab(E tabContent) { 396 397 Integer index = new Integer(m_tabPanel.getWidgetIndex(tabContent)); 398 Element tab = getTabElement(index.intValue()); 399 if ((tab != null) && m_disabledTabIndexes.containsKey(index)) { 400 tab.removeClassName(I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().tabDisabled()); 401 tab.setTitle(m_disabledTabIndexes.get(index)); 402 m_disabledTabIndexes.remove(index); 403 } 404 } 405 406 /** 407 * Returns the id of the selected tab.<p> 408 * 409 * @return the selected tab id 410 */ 411 public String getSelectedId() { 412 413 Widget tab = getWidget(m_tabPanel.getSelectedIndex()); 414 String tabId = null; 415 for (Entry<String, E> tabEntry : m_tabsById.entrySet()) { 416 if (tabEntry.getValue().equals(tab)) { 417 tabId = tabEntry.getKey(); 418 break; 419 } 420 } 421 return tabId; 422 } 423 424 /** 425 * Gets the index of the currently-selected tab.<p> 426 * 427 * Wrapper function for {@link com.google.gwt.user.client.ui.TabLayoutPanel#getSelectedIndex()} 428 * 429 * @return the selected index, or -1 if none is selected. 430 */ 431 public int getSelectedIndex() { 432 433 return m_tabPanel.getSelectedIndex(); 434 435 } 436 437 /** 438 * Measures the height of the tab bar.<p> 439 * 440 * @return the tab bar height 441 */ 442 public int getTabBarHeight() { 443 444 @SuppressWarnings("synthetic-access") 445 int result = m_tabPanel.m_tabBar.getOffsetHeight(); 446 return result; 447 448 } 449 450 /** 451 * Finds a tab with a given id.<p> 452 * 453 * @param tabId a tab id 454 * 455 * @return the tab with the given id 456 */ 457 public E getTabById(String tabId) { 458 459 return m_tabsById.get(tabId); 460 } 461 462 /** 463 * Gets the number of child widgets in this panel.<p> 464 * 465 * Wrapper function for {@link com.google.gwt.user.client.ui.TabLayoutPanel#getWidgetCount()} 466 * 467 * @return the number of children 468 */ 469 public int getTabCount() { 470 471 return m_tabPanel.getWidgetCount(); 472 } 473 474 /** 475 * Returns the index of the tab to the given child element.<p> 476 * 477 * @param child the tab child 478 * 479 * @return the tab index 480 */ 481 public int getTabIndex(Element child) { 482 483 int index = 0; 484 for (Widget tab : m_tabPanel) { 485 if (tab.getElement().isOrHasChild(child)) { 486 return index; 487 } 488 index++; 489 } 490 return -1; 491 } 492 493 /** 494 * Returns the tab text for a given tab.<p> 495 * 496 * @param pos the index of the tab 497 * 498 * @return the text of the tab 499 */ 500 public String getTabText(int pos) { 501 502 return m_tabPanel.getTabWidget(pos).getElement().getInnerText(); 503 } 504 505 /** 506 * Returns the tab widget.<p> 507 * This will not be the tab content but the tab itself.<p> 508 * 509 * @param index the tab index 510 * 511 * @return the tab widget 512 */ 513 public Widget getTabWidget(int index) { 514 515 return m_tabPanel.getTabWidget(index); 516 } 517 518 /** 519 * Gets the child widget at the specified index.<p> 520 * 521 * Wrapper function for {@link com.google.gwt.user.client.ui.TabLayoutPanel#getWidget(int)} 522 * 523 * @param tabIndex the child widget's index 524 * @return the child widget 525 */ 526 @SuppressWarnings("unchecked") 527 public E getWidget(int tabIndex) { 528 529 return (E)m_tabPanel.getWidget(tabIndex); 530 } 531 532 /** 533 * Inserts a widget into the panel. If the Widget is already attached, it will be moved to the requested index.<p> 534 * 535 * Wrapper function for {@link com.google.gwt.user.client.ui.TabLayoutPanel#insert(Widget, String, int)} 536 * 537 * @param tabContent the widget to be added 538 * @param tabName the text to be shown on its tab 539 * @param beforeIndex the index before which it will be inserted 540 */ 541 public void insert(E tabContent, String tabName, int beforeIndex) { 542 543 m_tabPanel.insert(tabContent, tabName, beforeIndex); 544 m_tabPanel.checkTabOverflow(); 545 } 546 547 /** 548 * Returns <code>true</code> if the tab with the given index is disabled, <code>false</code> otherwise.<p> 549 * 550 * @param tabIndex the tab index 551 * 552 * @return <code>true</code> if the tab with the given index is disabled, <code>false</code> otherwise 553 */ 554 public boolean isDisabledTab(int tabIndex) { 555 556 return m_disabledTabIndexes.containsKey(new Integer(tabIndex)); 557 } 558 559 /** 560 * Returns an iterator over all tabs.<p> 561 * 562 * @return the iterator 563 */ 564 @SuppressWarnings("unchecked") 565 public Iterator<E> iterator() { 566 567 return (Iterator<E>)m_tabPanel.iterator(); 568 } 569 570 /** 571 * @see org.opencms.gwt.client.I_CmsDescendantResizeHandler#onResizeDescendant() 572 */ 573 public void onResizeDescendant() { 574 575 if (m_autoResize) { 576 Widget w = m_tabPanel.getWidget(getSelectedIndex()); 577 if (w instanceof CmsTabContentWrapper) { 578 w = ((CmsTabContentWrapper)w).getWidget(); 579 } 580 int h = w.getOffsetHeight() + m_autoResizeHeightDelta; 581 setHeight(h + "px"); 582 } 583 } 584 585 /** 586 * Removes the tab with the given index.<p> 587 * 588 * @param tabIndex the index of the tab which should be removed 589 */ 590 public void removeTab(int tabIndex) { 591 592 m_tabPanel.remove(tabIndex); 593 m_tabPanel.checkTabOverflow(); 594 } 595 596 /** 597 * Delegate method.<p> 598 * 599 * @see com.google.gwt.user.client.ui.TabLayoutPanel#selectTab(Widget index) 600 * 601 * @param tabWidget the tab widget to select 602 */ 603 public void selectTab(E tabWidget) { 604 605 m_tabPanel.selectTab(tabWidget); 606 } 607 608 /** 609 * Delegate method.<p> 610 * 611 * @see com.google.gwt.user.client.ui.TabLayoutPanel#selectTab(Widget index) 612 * 613 * @param tabWidget the tab widget to select 614 * @param fireEvent <code>true</code> to fire the tab event 615 */ 616 public void selectTab(E tabWidget, boolean fireEvent) { 617 618 m_tabPanel.selectTab(tabWidget, fireEvent); 619 } 620 621 /** 622 * Delegate method.<p> 623 * 624 * @see com.google.gwt.user.client.ui.TabLayoutPanel#selectTab(int index) 625 * 626 * @param tabIndex the index of the tab to be selected 627 */ 628 public void selectTab(int tabIndex) { 629 630 m_tabPanel.selectTab(tabIndex); 631 } 632 633 /** 634 * Delegate method.<p> 635 * 636 * @see com.google.gwt.user.client.ui.TabLayoutPanel#selectTab(int index) 637 * 638 * @param tabIndex the index of the tab to be selected 639 * @param fireEvent <code>true</code> to fire the tab event 640 */ 641 public void selectTab(int tabIndex, boolean fireEvent) { 642 643 m_tabPanel.selectTab(tabIndex, fireEvent); 644 } 645 646 /** 647 * Enables or disables auto-resizing.<p> 648 * 649 * @param autoResize the auto resize flag value 650 */ 651 public void setAutoResize(boolean autoResize) { 652 653 m_autoResize = autoResize; 654 } 655 656 /** 657 * Sets a value which is added to the height of a tab content to change the tabbed panel height.<p> 658 * 659 * @param heightDelta the height difference 660 */ 661 public void setAutoResizeHeightDelta(int heightDelta) { 662 663 m_autoResizeHeightDelta = heightDelta; 664 } 665 666 /** 667 * Sets the text of a given tab.<p> 668 * 669 * @param pos the index of the tab 670 * @param text the new text for the tab 671 */ 672 public void setTabText(int pos, String text) { 673 674 m_tabPanel.setTabText(pos, text); 675 676 } 677 678 /** 679 * Returns the tab layout panel.<p> 680 * 681 * @return the tab layout panel 682 */ 683 protected TabLayoutPanel getTabPanel() { 684 685 return m_tabPanel; 686 } 687 688 /** 689 * @see com.google.gwt.user.client.ui.Widget#onLoad() 690 */ 691 @Override 692 protected void onLoad() { 693 694 super.onLoad(); 695 m_tabPanel.checkTabOverflow(); 696 // force layout after insertion into DOM to deal with IE layout problems 697 Scheduler.get().scheduleDeferred(new ScheduledCommand() { 698 699 public void execute() { 700 701 getTabPanel().forceLayout(); 702 703 } 704 }); 705 706 } 707 708 /** 709 * Sets the overflow of the tab layout content's parent to visible.<p> 710 */ 711 protected void setOverflowVisibleToContent() { 712 713 Element tabRoot = m_tabPanel.getElement(); 714 // set an additional css class for the parent element of the .gwt-TabLayoutPanelTabs element 715 List<Element> tabContentDivs = CmsDomUtil.getElementsByClass( 716 I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cmsTabLayoutPanelContent(), 717 CmsDomUtil.Tag.div, 718 tabRoot); 719 tabContentDivs.addAll( 720 CmsDomUtil.getElementsByClass("gwt-TabLayoutPanelContentContainer", CmsDomUtil.Tag.div, tabRoot)); 721 for (Element e : tabContentDivs) { 722 e.getParentElement().getStyle().setOverflow(Overflow.VISIBLE); 723 } 724 725 } 726 727 /** 728 * Returns the tab element for the given index.<p> 729 * 730 * @param tabIndex the tab index to get the tab element for 731 * 732 * @return the tab element for the given index 733 */ 734 private Element getTabElement(int tabIndex) { 735 736 Element tabRootEl = m_tabPanel.getElement(); 737 // set an additional css class for the parent element of the .gwt-TabLayoutPanelTabs element 738 List<Element> tabDivs = CmsDomUtil.getElementsByClass( 739 I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().cmsTabLayoutPanelTab(), 740 CmsDomUtil.Tag.div, 741 tabRootEl); 742 if ((tabDivs != null) && (tabDivs.size() > tabIndex)) { 743 return tabDivs.get(tabIndex); 744 } 745 return null; 746 } 747}