2012-01-12 2 views
1

Я использую GWT 2.4. У меня есть вкладка TabLayoutPanel, к которой я добавляю вкладки. Каждая вкладка содержит ScrollPanel. Мой вопрос: как сделать вкладки в переносе панели вкладок на следующую строку, если ширина панели вкладок превышает видимую ширину?GWT: В TabLayoutPanel, как я могу сделать вкладки, если их слишком много?

Спасибо, - Дэйв

+3

не ответ, но, если у вас есть слишком много из них, что, вероятно, является признаком плохого дизайна, который хочет, чтобы просканировать- ряды вкладок в любом случае. Амазонка имела обыкновение иметь их несколько лет назад, вы все равно можете найти моментальные снимки на archive.org, посмотрите. – milan

+0

@milan - Я думаю, чтобы убрать вкладку Tab, поскольку плохой дизайн слишком упрощен. Вы когда-нибудь открывали много вкладок в браузере? Любая ситуация с пользовательским интерфейсом, когда пользователь может открывать вкладки, почти всегда требует переноса вкладок. –

+0

@kabram Я сказал «признак плохого дизайна» :) и да, у меня есть много вкладок, открытых в моих браузерах, но ни один из браузеров не завершает их, например. Я прав? – milan

ответ

1

GWT-х TabLayoutPanel намеренно не оборачивает вкладок. См. Строки 246-248 в TabLayoutPanel.java - (line 217 определяет private static final int BIG_ENOUGH_TO_NOT_WRAP = 16384). Возможно, вы сможете переопределить это, но, как говорит @milan, это, вероятно, не очень хороший дизайн.

1

Наличие нескольких линий, на самом деле, не рекомендуется ...

Однако, чтобы иметь возможность перемещаться влево/вправо на одной панели вкладок с большим количеством вкладок, вы можете использовать этот рецепт: http://devnotesblog.wordpress.com/2010/06/17/scrollable-gwt-tablayoutpanel/

И обновленная реализация, которая не использует устаревшую DeferredCommand:

package whatever.you.want; 

import com.google.gwt.core.client.Scheduler; 
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.ResizeEvent; 
import com.google.gwt.event.logical.shared.ResizeHandler; 
import com.google.gwt.event.shared.HandlerRegistration; 
import com.google.gwt.resources.client.ImageResource; 
import com.google.gwt.user.client.Window; 
import com.google.gwt.user.client.ui.FlowPanel; 
import com.google.gwt.user.client.ui.Image; 
import com.google.gwt.user.client.ui.LayoutPanel; 
import com.google.gwt.user.client.ui.TabLayoutPanel; 
import com.google.gwt.user.client.ui.Widget; 

/** 
* A {@link TabLayoutPanel} that shows scroll buttons if necessary 
*/ 
public class ScrolledTabLayoutPanel extends TabLayoutPanel { 

     private static final int IMAGE_PADDING_PIXELS = 4; 

     private LayoutPanel panel; 
     private FlowPanel tabBar; 
     private Image scrollLeftButton; 
     private Image scrollRightButton; 
     private HandlerRegistration windowResizeHandler; 

     private ImageResource leftArrowImage; 
     private ImageResource rightArrowImage; 

     public ScrolledTabLayoutPanel(double barHeight, Unit barUnit, 
      ImageResource leftArrowImage, ImageResource rightArrowImage) { 
       super(barHeight, barUnit); 

       this.leftArrowImage = leftArrowImage; 
       this.rightArrowImage = rightArrowImage; 

       // The main widget wrapped by this composite, which is a LayoutPanel with the tab bar & the tab content 
       panel = (LayoutPanel) getWidget(); 

       // Find the tab bar, which is the first flow panel in the LayoutPanel 
       for (int i = 0; i < panel.getWidgetCount(); ++i) { 
         Widget widget = panel.getWidget(i); 
         if (widget instanceof FlowPanel) { 
           tabBar = (FlowPanel) widget; 
           break; // tab bar found 
         } 
       } 

       initScrollButtons(); 
     } 

     @Override 
     public void add(Widget child, Widget tab) { 
       super.add(child, tab); 
       checkIfScrollButtonsNecessary(); 
     } 

     @Override 
     public boolean remove(Widget w) { 
       boolean b = super.remove(w); 
       checkIfScrollButtonsNecessary(); 
       return b; 
     } 

     @Override 
     protected void onLoad() { 
       super.onLoad(); 

       if (windowResizeHandler == null) { 
         windowResizeHandler = Window.addResizeHandler(new ResizeHandler() { 
           @Override 
           public void onResize(ResizeEvent event) { 
             checkIfScrollButtonsNecessary(); 
           } 
         }); 
       } 
     } 

     @Override 
     protected void onUnload() { 
       super.onUnload(); 

       if (windowResizeHandler != null) { 
         windowResizeHandler.removeHandler(); 
         windowResizeHandler = null; 
       } 
     } 

     private ClickHandler createScrollClickHandler(final int diff) { 
       return new ClickHandler() { 
         @Override 
         public void onClick(ClickEvent event) { 
           Widget lastTab = getLastTab(); 
           if (lastTab == null) 
             return; 

           int newLeft = parsePosition(tabBar.getElement().getStyle().getLeft()) + diff; 
           int rightOfLastTab = getRightOfWidget(lastTab); 

           // Prevent scrolling the last tab too far away form the right border, 
           // or the first tab further than the left border position 
           if (newLeft <= 0 && (getTabBarWidth() - newLeft < (rightOfLastTab + 20))) { 
             scrollTo(newLeft); 
           } 
         } 
       }; 
     } 

     /** Create and attach the scroll button images with a click handler */ 
     private void initScrollButtons() { 
       scrollLeftButton = new Image(leftArrowImage); 
       int leftImageWidth = scrollLeftButton.getWidth(); 
       panel.insert(scrollLeftButton, 0); 
       panel.setWidgetLeftWidth(scrollLeftButton, 0, Unit.PX, leftImageWidth, Unit.PX); 
       panel.setWidgetTopHeight(scrollLeftButton, 0, Unit.PX, scrollLeftButton.getWidth(), Unit.PX); 
       scrollLeftButton.addClickHandler(createScrollClickHandler(+20)); 
       scrollLeftButton.setVisible(false); 

       scrollRightButton = new Image(rightArrowImage); 
       panel.insert(scrollRightButton, 0); 
       panel.setWidgetLeftWidth(scrollRightButton, leftImageWidth + IMAGE_PADDING_PIXELS, Unit.PX, scrollRightButton.getWidth(), Unit.PX); 
       panel.setWidgetTopHeight(scrollRightButton, 0, Unit.PX, scrollRightButton.getHeight(), Unit.PX); 

       scrollRightButton.addClickHandler(createScrollClickHandler(-20)); 
       scrollRightButton.setVisible(false); 
     } 

     private void checkIfScrollButtonsNecessary() { 
       // Defer size calculations until sizes are available, when calculating immediately after 
       // add(), all size methods return zero 
      Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { 

       @Override 
       public void execute() { 
        boolean isScrolling = isScrollingNecessary(); 
        // When the scroll buttons are being hidden, reset the scroll position to zero to 
        // make sure no tabs are still out of sight 
        if (scrollRightButton.isVisible() && !isScrolling) { 
          resetScrollPosition(); 
        } 
        scrollRightButton.setVisible(isScrolling); 
        scrollLeftButton.setVisible(isScrolling); 
       } 

      } 
      ); 

     } 

     private void resetScrollPosition() { 
       scrollTo(0); 
     } 

     private void scrollTo(int pos) { 
       tabBar.getElement().getStyle().setLeft(pos, Unit.PX); 
     } 

     private boolean isScrollingNecessary() { 
       Widget lastTab = getLastTab(); 
       if (lastTab == null) 
         return false; 

       return getRightOfWidget(lastTab) > getTabBarWidth(); 
     } 

     private int getRightOfWidget(Widget widget) { 
       return widget.getElement().getOffsetLeft() + widget.getElement().getOffsetWidth(); 
     } 

     private int getTabBarWidth() { 
       return tabBar.getElement().getParentElement().getClientWidth(); 
     } 

     private Widget getLastTab() { 
       if (tabBar.getWidgetCount() == 0) 
         return null; 

       return tabBar.getWidget(tabBar.getWidgetCount() - 1); 
     } 

     private static int parsePosition(String positionString) { 
       int position; 
       try { 
         for (int i = 0; i < positionString.length(); i++) { 
           char c = positionString.charAt(i); 
           if (c != '-' && !(c >= '0' && c <= '9')) { 
             positionString = positionString.substring(0, i); 
           } 
         } 

         position = Integer.parseInt(positionString); 
       } catch (NumberFormatException ex) { 
         position = 0; 
       } 
       return position; 
     } 
} 
Смежные вопросы