Re: TabLayoutPanel with scroll buttons
I experienced the challenge to make GWT TabLayoutPanel to act as the Smart GWT one (http://www.smartclient.com/smartgwt/showcase/#layout_tabs_add_remove). I took PhiLho code as the starting point, big thanks to him. So, my improvements and changes are: 1. Both scroll buttons are in the right corner now, next to each other and wrapped in HorizontalPanel. 2. The third button added, for showing the popup menu with the list of all tabs for selecting. 3. Scrolling value now is not fixed rather equal the width of next tab to show 4. Scrolling is animated 5. Widget reacts now not only on browser window resize, but on widget itself resize too (i replace window on resize handler with overriding widget onResize() method) 6. selectTab() method is also overrided for automatic scrolling if new selected tab is not in visible area The code is in attachment. Hope, someone else find it useful. -- You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscr...@googlegroups.com. To post to this group, send email to google-web-toolkit@googlegroups.com. Visit this group at http://groups.google.com/group/google-web-toolkit. For more options, visit https://groups.google.com/d/optout. package gwt_widgets_test.client.widgets; import com.google.gwt.animation.client.Animation; import com.google.gwt.cell.client.SafeHtmlCell; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.Style; 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.resources.client.ClientBundle; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlUtils; import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.*; import com.google.gwt.view.client.SelectionChangeEvent; import com.google.gwt.view.client.SingleSelectionModel; import java.util.ArrayList; import java.util.List; /** * A {@link TabLayoutPanel} that shows scroll buttons if necessary. * https://groups.google.com/forum/?fromgroups=#!topic/google-web-toolkit/wN8lLU23wPA */ public class ScrollableTabLayoutPanel extends TabLayoutPanel { private static final String SCROLL_BUTTON_STYLE = gwt-TabLayoutPanelScrollButton; private static final String SCROLL_PANEL_STYLE = gwt-TabLayoutPanelScrollPanel; private final double barHeight; private final Unit barUnit; private final Resources resources; //tabLayoutPanel root widget private LayoutPanel panel; private FlowPanel tabBar; private HorizontalPanel scrollPanel; private static Resources DEFAULT_RESOURCES; public ScrollableTabLayoutPanel() { this(30, Unit.PX); } public ScrollableTabLayoutPanel(double barHeight, Unit barUnit) { this(barHeight, barUnit, getDefaultResources()); } public ScrollableTabLayoutPanel(double barHeight, Unit barUnit, Resources resources) { super(barHeight, barUnit); this.barUnit = barUnit; this.barHeight = barHeight; this.resources = resources; // 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; } } initScrollButtons(); } @Override public void onResize() { super.onResize(); showScrollButtonsIfNecessary(); } @Override public void insert(Widget child, Widget tab, int beforeIndex) { super.insert(child, tab, beforeIndex); showScrollButtonsIfNecessary(); } @Override public boolean remove(int index) { boolean b = super.remove(index); showScrollButtonsIfNecessary(); return b; } @Override public void selectTab(int index, boolean fireEvents) { super.selectTab(index, fireEvents); //all the code below is for automatic scrolling if selected tab is out of visible area Widget selectedTab = tabBar.getWidget(getSelectedIndex()); int visibleAreaLeftBorder = Math.abs(getCurrentShift()); int visibleAreaRightBorder = visibleAreaLeftBorder + getTabBarWidth(); int halfVisibleAreaWidth = getTabBarWidth() / 2; int halfTabWidth = (getRightPosition(selectedTab
Re: TabLayoutPanel with scroll buttons
By popular demand (my own taste, and a request of a tester), I hide a button when we can no longer scroll in this direction... I replaced the hackish test: if (scrollRightButton.isVisible()) with a specialized field: private boolean isScrolling; The following are the added / modified methods with regard to my previous message: private void adjustScroll(int diff) { int newLeft = parsePosition(tabBar.getElement().getStyle().getLeft()) + diff; if (newLeft = 0) { int gap = computeGap(); if (gap -newLeft) { // If we are about to scroll too far away from the right border, adjust back newLeft += -newLeft - gap; } } else { // Don't scroll for a positive newLeft newLeft = 0; } scrollTo(newLeft); } /** * Gap = distance between right of last tab and right of the tab bar. */ private int computeGap() { Widget lastTab = getLastTab(); if (lastTab == null) return 0; return getRightPosition(lastTab) - getTabBarWidth(); } private void showScrollButtonsIfNecessary() { // 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 shouldScroll = isScrollingNecessary(); if (isScrolling) { if (!shouldScroll) { // The scroll buttons are being hidden, reset the scroll position to zero to avoid // having tabs starting in the middle of the window! scrollTo(0); } else { // Resizing or adding / removing tabs, recompute the scroll adjustScroll(0); } } else { // Was not scrolling, show leftmost tab and adjust scroll button visibility scrollTo(0); } } }); } private void scrollTo(int pos) { tabBar.getElement().getStyle().setLeft(pos, Unit.PX); // Change visibility of the scroll buttons, depending on the current scrolling isScrolling = pos 0; // Visible if not in the rightmost position scrollLeftButton.setVisible(isScrolling); // Visible if not in the leftmost position (and if we must scroll) scrollRightButton.setVisible(isScrollingNecessary() computeGap() != -pos); } HTH. -- Philippe Lhoste -- (near) Paris -- France -- http://Phi.Lho.free.fr -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscr...@googlegroups.com. To post to this group, send email to google-web-toolkit@googlegroups.com. Visit this group at http://groups.google.com/group/google-web-toolkit?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: TabLayoutPanel with scroll buttons
An update: I prefer to have the scroll buttons on each side of the tabs, and I reduced the tab bar so it is not under the buttons. I put the images in divs (SimplePanel) for further CSS styling (adding cursor: pointer; for example). And I fixed a bug in my previous version: when the bar is scrolled to the right, and the window is widened, the gap on the left was not closed and we could no longer scroll. Here is the improved version: 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.Element; 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.SimplePanel; 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. * https://groups.google.com/forum/?fromgroups=#!topic/google-web-toolkit/wN8lLU23wPA */ public class ScrollableTabLayoutPanel extends TabLayoutPanel { private static final String SCROLL_BUTTON_STYLE = tab-scroll-button; private static final int SCROLL_INTERVAL = 60; private LayoutPanel panel; private FlowPanel tabBar; private HandlerRegistration windowResizeHandler; private SimplePanel scrollLeftButton; private SimplePanel scrollRightButton; private ImageResource leftArrowImage; private ImageResource rightArrowImage; public ScrollableTabLayoutPanel(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; } } initScrollButtons(); } @Override public void insert(Widget child, Widget tab, int beforeIndex) { super.insert(child, tab, beforeIndex); showScrollButtonsIfNecessary(); } @Override public boolean remove(int index) { boolean b = super.remove(index); showScrollButtonsIfNecessary(); return b; } @Override protected void onLoad() { super.onLoad(); if (windowResizeHandler == null) { windowResizeHandler = Window.addResizeHandler(new ResizeHandler() { @Override public void onResize(ResizeEvent event) { showScrollButtonsIfNecessary(); } }); } } @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) { adjustScroll(diff); } }; } private void adjustScroll(int diff) { Widget lastTab = getLastTab(); if (lastTab == null) return; int newLeft = parsePosition(tabBar.getElement().getStyle().getLeft()) + diff; int rightOfLastTab = getRightPosition(lastTab); // Don't scroll for a positive newLeft if (newLeft = 0) { // If we are about to scroll too far away from the right border, adjust back int gap = rightOfLastTab - getTabBarWidth(); if (gap -newLeft) { newLeft += -newLeft - gap; } scrollTo(newLeft); } else { scrollTo(0); } } /** * Create and attach the scroll button images with a click handler */ private void initScrollButtons() { Image scrollLeftButtonImage = new Image(leftArrowImage); Image scrollRightButtonImage = new Image(rightArrowImage); int leftArrowWidth = scrollLeftButtonImage.getWidth
Re: TabLayoutPanel with scroll buttons
I updated the code of Eze for GWT 2.5. Apparently, the lastScroll trick is no longer needed, and I override the root insert / delete methods to reduce the number of overrides. There was also a little bug, using scrollLeftButton.getWidth() in place of scrollLeftButton.getHeight(), visible when the buttons are not square... I renamed also some methods to my taste. :-) There are still some things to improve, as I don't like the buttons to be over the first tab, but I will look into it later. Here is my variant: 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. * https://groups.google.com/forum/?fromgroups=#!topic/google-web-toolkit/wN8lLU23wPA */ public class ScrollableTabLayoutPanel extends TabLayoutPanel { private static final int IMAGE_PADDING_PIXELS = 4; private static final int SCROLL_INTERVAL = 60; private LayoutPanel panel; private FlowPanel tabBar; private HandlerRegistration windowResizeHandler; private Image scrollLeftButton; private Image scrollRightButton; private ImageResource leftArrowImage; private ImageResource rightArrowImage; public ScrollableTabLayoutPanel(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; } } initScrollButtons(); } @Override public void insert(Widget child, Widget tab, int beforeIndex) { super.insert(child, tab, beforeIndex); showScrollButtonsIfNecessary(); } @Override public boolean remove(int index) { boolean b = super.remove(index); showScrollButtonsIfNecessary(); return b; } @Override protected void onLoad() { super.onLoad(); if (windowResizeHandler == null) { windowResizeHandler = Window.addResizeHandler(new ResizeHandler() { @Override public void onResize(ResizeEvent event) { showScrollButtonsIfNecessary(); } }); } } @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 = getRightPosition(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 - diff / 2)) { 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.getHeight(), Unit.PX); scrollLeftButton.addClickHandler
Re: TabLayoutPanel with scroll buttons
please can you show me how to use it , i coudn't even test it ! -- You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/RUADpqouugoJ. To post to this group, send email to google-web-toolkit@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: TabLayoutPanel with scroll buttons
hi , please can help me understand what do you mean by saying You should be able to wrap it into a Composite and then reference that Composite in your UiBinder file though. ?? and i m searching for a widget that can help me do this http://www.youtube.com/watch?v=bUDpr-v-jHAfeature=relmfu (in 1:56) , is this code is what i am looking for ? I used a tablayoutpanel and when it comes to doing scrollable tabs , i foud your code !! but i can't be sure ! -- You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/8IzF8Q40Gp8J. To post to this group, send email to google-web-toolkit@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: TabLayoutPanel with scroll buttons
Hi, I modified this for gwt 2.2.0, and some minor fixes (selecting a tab was causing scoll to 0) BTW thanks to Matt for the first version, it saved me a lot of work package com.gwtscrolledtablayoutpanel.ui; 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.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; 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.*; /** * 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; private static final int SCROLL_INTERVAL = 60; private HandlerRegistration selectionHandler; private int lastScroll = 0; 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 w) { super.add(w); checkIfScrollButtonsNecessary(); } @Override public void add(Widget child, String text) { super.add(child, text); checkIfScrollButtonsNecessary(); } @Override public void add(Widget child, String text, boolean asHtml) { super.add(child, text, asHtml); checkIfScrollButtonsNecessary(); } @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(); } }); } if (selectionHandler == null) { selectionHandler = addSelectionHandler(new SelectionHandlerInteger() { public void onSelection(SelectionEventInteger selectedEvent) { doOnSelectTab(selectedEvent.getSelectedItem()); } }); } } @Override protected void onUnload() { super.onUnload(); if (windowResizeHandler != null) { windowResizeHandler.removeHandler(); windowResizeHandler = null; } if (selectionHandler != null) { selectionHandler.removeHandler(); selectionHandler = null; } } private void doOnSelectTab(int selected) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { public void execute() { scrollTo(lastScroll); } }); } 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 - diff / 2))) { 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
Re: TabLayoutPanel with scroll buttons
Hi, you won't be able to use this custom widget directly within an UiBinder file due to this issue: http://code.google.com/p/google-web-toolkit/issues/detail?id=4342. You should be able to wrap it into a Composite and then reference that Composite in your UiBinder file though. Hth, Matt On 18 Mai, 15:58, rkvaja rikesh.v...@gmail.com wrote: I'm trying to use this with UIBinder but getting issues telling me that I am missing required attributes barUnit, barHeight etc. Has anybody got this working with UIBinder? You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To post to this group, send email to google-web- tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit +unsubscr...@googlegroups.com. For more options, visit this group athttp://groups.google.com/group/google-web-toolkit?hl=en. -- You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group athttp://groups.google.com/group/google-web-toolkit?hl=en. -- You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: TabLayoutPanel with scroll buttons
I'm trying to use this with UIBinder but getting issues telling me that I am missing required attributes barUnit, barHeight etc. Has anybody got this working with UIBinder? You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To post to this group, send email to google-web- tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit +unsubscr...@googlegroups.com. For more options, visit this group athttp://groups.google.com/group/google-web-toolkit?hl=en. -- You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
Re: TabLayoutPanel with scroll buttons
Awesome. This saved me a few days work ! Thank you ! Small error, forgot to initialize the local image vars in the constructor though: ... super(barHeight, barUnit); this.leftArrowImage = leftArrowImage; this.rightArrowImage = rightArrowImage; ... -- You received this message because you are subscribed to the Google Groups Google Web Toolkit group. To post to this group, send email to google-web-tool...@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
TabLayoutPanel with scroll buttons
Hi, the GWT TabLayoutPanel doesn't show scroll buttons if the visible panel bar becomes smaller then width of all open tab headers. There is an enhacement request issue pending that might be implemented in a future version of GWT, until then you might find the attached code snippet useful that extends TabLayoutPanel to show scroll buttons if necessary. Cheers, Matt package com.gwtscrolledtablayoutpanel.ui; 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.Command; import com.google.gwt.user.client.DeferredCommand; 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); // 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