public void setTabs(TwoLevelTab... tabs) {
   super.setTabs(tabs);
   for (TwoLevelTab tab : tabs) {
     tab.getLayout().addTwoLevelTabSelectedHandler(this);
     updateTab(tab, tab.getPane());
   }
   buildTabList();
   addTabSelectedHandler(this);
 }
 public TwoLevelTab getDefaultTab() {
   TwoLevelTab[] tabs = getTabs();
   for (TwoLevelTab tab : tabs) {
     if (!tab.getDisabled()) {
       return tab;
     }
   }
   return null;
 }
 /**
  * This method initializes the head and tail pointers. Then it initializes the {@link
  * TwoLevelTab#getActualNext actualNext} and {@link TwoLevelTab#getVisibleNext visibleNext}
  * properties of each tab. This list is built so that when hiding and showing tabs, the tab order
  * remains consistent. The order of the list is the same as the order of the tabs passed to {@link
  * #setTabs(TwoLevelTab...)}
  */
 private void buildTabList() {
   TwoLevelTab[] tabs = getTabs();
   head = tabs[0];
   tail = tabs[tabs.length - 1];
   TwoLevelTab current = head;
   for (int i = 1; i < tabs.length; ++i) {
     current.setActualNext(tabs[i]);
     current.setVisibleNext(tabs[i]);
     current = tabs[i];
   }
 }
 @Override
 public void destroy() {
   // add the hidden tabs back under the TabSet. This will get them destroyed by smartgwt when the
   // tabset
   // goes away. There is no explicit Tab.destroy().
   for (TwoLevelTab tab : hiddenTabs.values()) {
     addTab(tab);
   }
   for (TwoLevelTab tab : getTabs()) {
     tab.getLayout().destroyViews();
   }
   super.destroy();
 }
 /**
  * Walks the list to find the closest, visible successor.
  *
  * @param tab A {@link TwoLevelTab tab} that is currently hidden
  * @return The closest, visisble successor or null if the insertion point is the tail.
  */
 private TwoLevelTab findClosestVisibleSuccessor(TwoLevelTab tab) {
   TwoLevelTab current = tab;
   while (current != null) {
     // Walk the list of tabs until we reach a visible successor or the tail
     if (current.getVisibleNext() == null && current != tail) {
       current = current.getActualNext();
     } else {
       return current;
     }
   }
   // if we reach this point then that means we will be inserting at the tail
   return null;
 }
  /**
   * Walks the list of tabs to find the closest, visible predecessor.
   *
   * @param tab A {@link TwoLevelTab tab} that is currently visible
   * @return The closest, visible predecessor or null if have the head
   */
  private TwoLevelTab findClosestVisiblePredecessor(TwoLevelTab tab) {
    if (tab == head) {
      return null;
    }

    TwoLevelTab current = head;
    while (current != tab) {
      // if we have reached the visible tail or the immediate predecessor
      // of the tab, then return it.
      if (current.getVisibleNext() == null || current.getVisibleNext() == tab) {
        return current;
      }
      current = current.getVisibleNext();
    }
    // Not sure what we should do if we get here. return null for now
    return null;
  }
  // This is invoked by smartgwt when the user clicks on a Tab in the TabSet, or TabSet.selectTab()
  // is called. It
  // sets the current SubTab and fires an event to notify AbstractTwoLevelTabSet that a tab/subtab
  // has been selected.
  public void onTabSelected(TabSelectedEvent tabSelectedEvent) {
    // if requested, ignore select tab notifications. smartgwt can generate unwanted notifications
    // while we manipulate the tabset (e.g. when hiding the current tab). We want to manage this at
    // a higher level
    if (isIgnoreSelectEvents()) {
      return;
    }

    TwoLevelTab tab = (TwoLevelTab) getSelectedTab();
    SubTab currentSubTab = tab.getLayout().getCurrentSubTab();
    if (null != currentSubTab) {
      TwoLevelTabSelectedEvent event =
          new TwoLevelTabSelectedEvent(
              tab.getName(),
              tab.getLayout().getCurrentSubTab().getName(),
              tabSelectedEvent.getTabNum(),
              tab.getLayout().getCurrentCanvas(),
              History.getToken());
      m.fireEvent(event);
    }
  }
 public void destroyViews() {
   for (TwoLevelTab tab : getTabs()) {
     tab.getLayout().destroyViews();
   }
 }
  // Smartgwt does not currently offer the ability to hide a Tab (why!) so we fake it here.  This
  // allows us to keep
  // the Tab structure in place while removing it from the TabSet
  public void setTabHidden(TwoLevelTab tab, boolean hidden) {
    if (hidden) {
      if (hiddenTabs.containsKey(tab.getLocatorId())) {
        return;
      }

      TwoLevelTab visiblePrevious = findClosestVisiblePredecessor(tab);
      if (visiblePrevious == null) {
        // if visiblePrevious is null then that means we are updating
        // then head. Note that as of now (02/21/2012), the visible head,
        // the summary tab, is fixed, so we don't really need to worry
        // about updating the head; however, doing so will make it easier
        // to support things like hiding arbitrary tabs or reordering tabs.
        head = tab.getVisibleNext();

      } else {
        visiblePrevious.setVisibleNext(tab.getVisibleNext());
        // check to see if the tail needs to be updated. If the
        // following check is true, then that means visiblePrevious is
        // now the tail.
        if (visiblePrevious.getVisibleNext() == null) {
          tail = visiblePrevious;
        }
      }
      tab.setVisibleNext(null);
      // Note that removing the tab does *not* destroy its content pane
      // since we set the destroyPanes property to false in the
      removeTab(tab);
      hiddenTabs.put(tab.getLocatorId(), tab);
    } else {
      if (!hiddenTabs.containsKey(tab.getLocatorId())) {
        return;
      }

      hiddenTabs.remove(tab.getLocatorId());
      TwoLevelTab successor = findClosestVisibleSuccessor(tab);
      if (successor == null) {
        // if successor is null then that means we are updating the tail
        tail.setVisibleNext(tab);
        tail = tab;
        addTab(tab);
      } else {
        TwoLevelTab visiblePrevious = findClosestVisiblePredecessor(successor);
        tab.setVisibleNext(visiblePrevious.getVisibleNext());
        visiblePrevious.setVisibleNext(tab);
        addTab(tab, (getTabNumber(visiblePrevious.getID()) + 1));
      }
    }
  }