GWT: В TabLayoutPanel, как сделать перенос вкладок, если их слишком много? - PullRequest
1 голос
/ 12 января 2012

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

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

Ответы [ 2 ]

1 голос
/ 26 января 2012

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

Однако, чтобы иметь возможность перемещаться влево / вправо на одной панели вкладок со многими вкладками, вы можете использовать этот рецепт: 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;
        }
}
1 голос
/ 12 января 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...