Java tutorial
/** * Sencha GXT 3.1.1 - Sencha for GWT * Copyright(c) 2007-2014, Sencha, Inc. * licensing@sencha.com * * http://www.sencha.com/products/gxt/license/ */ package com.sencha.gxt.desktop.client.widget; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.uibinder.client.UiChild; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import com.sencha.gxt.core.client.dom.XDOM; import com.sencha.gxt.core.client.dom.XElement; import com.sencha.gxt.core.client.util.Margins; import com.sencha.gxt.core.client.util.Size; import com.sencha.gxt.widget.core.client.container.HBoxLayoutContainer.HBoxLayoutAlign; import com.sencha.gxt.widget.core.client.container.InsertResizeContainer; import com.sencha.gxt.widget.core.client.container.MarginData; import com.sencha.gxt.widget.core.client.container.VBoxLayoutContainer.VBoxLayoutAlign; /** * Arranges widgets in a top-down, left-to-right manner. The container is * divided into a grid of equal sized cells based on the width and height of the * largest widget. Widgets are then positioned in these cells based on the * settings of {@link HBoxLayoutAlign} and {@link VBoxLayoutAlign} to produce a * series of columns and rows. Widgets are arranged in each column in a top-down * order, starting with the left-most column and proceeding to the right. */ public class DesktopLayoutContainer extends InsertResizeContainer { public interface DesktopLayoutContainerAppearance { public XElement getShortcutArea(XElement parent); public void render(SafeHtmlBuilder sb); } private HBoxLayoutAlign hBoxLayoutAlign; private VBoxLayoutAlign vBoxLayoutAlign; private DesktopLayoutContainerAppearance appearance; /** * Creates a desktop layout container with the default appearance. */ public DesktopLayoutContainer() { this(GWT.<DesktopLayoutContainerAppearance>create(DesktopLayoutContainerAppearance.class)); } /** * Creates a desktop layout container with the specified appearance. * * @param appearance the desktop layout container appearance */ public DesktopLayoutContainer(DesktopLayoutContainerAppearance appearance) { this.appearance = appearance; forceLayoutOnResize = true; setHBoxLayoutAlign(HBoxLayoutAlign.MIDDLE); setVBoxLayoutAlign(VBoxLayoutAlign.CENTER); SafeHtmlBuilder sb = new SafeHtmlBuilder(); appearance.render(sb); setElement((Element) XDOM.create(sb.toSafeHtml())); } /** * Adds a widget to this desktop layout container with the specified layout * parameters. * * @param child the widget to add * @param layoutData the layout parameters */ @UiChild(tagname = "child") public void add(IsWidget child, MarginData layoutData) { if (child != null) { child.asWidget().setLayoutData(layoutData); } add(child); } /** * Returns the horizontal alignment. * * @return the horizontal alignment */ public HBoxLayoutAlign getHBoxLayoutAlign() { return hBoxLayoutAlign; } /** * Returns the vertical alignment. * * @return the vertical alignment */ public VBoxLayoutAlign getVBoxLayoutAlign() { return vBoxLayoutAlign; } /** * Sets the horizontal alignment for child items (defaults to * {@link HBoxLayoutAlign#MIDDLE}). * * @param hBoxLayoutAlign the horizontal alignment */ public void setHBoxLayoutAlign(HBoxLayoutAlign hBoxLayoutAlign) { this.hBoxLayoutAlign = hBoxLayoutAlign; } /** * Sets the vertical alignment for child items (defaults to * {@link VBoxLayoutAlign#CENTER}). * * @param vBoxLayoutAlign the vertical alignment */ public void setVBoxLayoutAlign(VBoxLayoutAlign vBoxLayoutAlign) { this.vBoxLayoutAlign = vBoxLayoutAlign; } @Override protected void doLayout() { int widgetCount = getWidgetCount(); if (widgetCount == 0) { return; } int maxWidth = 0; int maxHeight = 0; for (int i = 0; i < widgetCount; i++) { Widget widget = getWidget(i); Margins margins = getMargins(widget); maxWidth = Math.max(maxWidth, widget.getOffsetWidth() + margins.getLeft() + margins.getRight()); maxHeight = Math.max(maxHeight, widget.getOffsetHeight() + margins.getTop() + margins.getBottom()); } XElement element = getElement(); Size size = XElement.as(element).getStyleSize(); int availableHeight = size.getHeight() - XDOM.getScrollBarWidth(); int rowCount = availableHeight / maxHeight; int columnCount = (widgetCount + (rowCount - 1)) / rowCount; int requiredWidth = columnCount * maxWidth; getContainerTarget().setSize(requiredWidth, availableHeight); for (int i = 0; i < widgetCount; i++) { Widget widget = getWidget(i); Margins margins = getMargins(widget); int row = i % rowCount; int column = i / rowCount; int left = column * maxWidth; int top = row * maxHeight; int widgetWidth = widget.getOffsetWidth(); int widgetHeight = widget.getOffsetHeight(); int marginWidth = margins.getLeft() + margins.getRight(); int marginHeight = margins.getTop() + margins.getBottom(); int excessWidth = maxWidth - widgetWidth - marginWidth; int excessHeight = maxHeight - widgetHeight - marginHeight; boolean isSizeChange = false; switch (vBoxLayoutAlign) { case CENTER: left += excessWidth / 2; break; case LEFT: // no action required break; case RIGHT: left += excessWidth; break; case STRETCH: case STRETCHMAX: default: widgetWidth = maxWidth - marginWidth; isSizeChange = true; break; } switch (hBoxLayoutAlign) { case TOP: // no action required break; case MIDDLE: top += excessHeight / 2; break; case BOTTOM: top += excessHeight; break; case STRETCH: case STRETCHMAX: default: widgetHeight = maxHeight - marginHeight; isSizeChange = true; break; } XElement.as(widget.getElement()).makePositionable(true); XElement.as(widget.getElement()).setLeftTop(left, top); if (isSizeChange) { applyLayout(widget, widgetWidth, widgetHeight); } } } protected XElement getContainerTarget() { return appearance.getShortcutArea(getElement()); } private Margins getMargins(Widget widget) { Margins margins = null; Object layoutData = widget.getLayoutData(); if (layoutData instanceof MarginData) { MarginData marginData = (MarginData) layoutData; margins = marginData.getMargins(); } return margins == null ? new Margins(0) : margins; } }