I've been experimenting with
GWT and
GWT Designer lately. I get the feeling that a version or two down the road, these are going to give me a massive productivity boost. Right now, I still find myself stuck trying to figure out why things aren't working as I expect.
For example the new GWT 2.0
Layout framework does not sit well with the pre-2.0 widgets such as
DecoratorPanel. Try adding a
LayoutPanel to a DecoratorPanel - it won't work, you'll just see nothing inside the DecoratorPanel.
To get round this, I've implemented a DecoratorLayoutPanel, which subclasses
LayoutPanel and so can contain any Layout-compatible widgets. I've added the source code below - feel free to copy/reuse/extend as you like, and I'd welcome any feedback!
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* <p>
* A {@link LayoutPanel} that wraps its contents in stylized boxes, which can be
* used to add rounded corners to a {@link Widget}.
* </p>
* <p>
* This class aims to be a drop-in replacement for
* {@link com.google.gwt.user.client.ui.DecoratorPanel}.
* However, it uses a {@link LayoutPanel} to layout the 9-box, whereas
* {@link com.google.gwt.user.client.ui.DecoratorPanel} uses a DOM table.
* The benefit is that this panel can contain other {@link LayoutPanel} widgets, which
* {@link com.google.gwt.user.client.ui.DecoratorPanel} cannot do successfully.
* </p>
* <p>
* All of the same class names used in {@link com.google.gwt.user.client.ui.DecoratorPanel}
* are used here, e.g. .gwt-DecoratorPanel, .topCenter, .bottomRightInner
* </p>
* <p>
* Important differences to {@link com.google.gwt.user.client.ui.DecoratorPanel}:
* <ul>
* <li>.middleCenter should not be given height and width of 100%, as this will cause
* unexpected behaviour.</li>
* <li>The size of the corners is set in the constructor, but note that this can be
* overridden in CSS.</li>
* </ul>
* </p>
*/
public class DecoratorLayoutPanel extends LayoutPanel implements AcceptsOneWidget {
/**
* The default style name.
*/
private static final String DEFAULT_STYLENAME = "gwt-DecoratorPanel";
/**
* Wrapper for middle center widget.
*/
private LayoutPanel container;
/**
* Middle center widget
*/
private Widget widget;
/**
* Create new instance using default size of corners.
*/
public DecoratorLayoutPanel() {
this(5, Unit.PX);
}
/**
* Create new instance using specified size of corners.
*
* @param size Height and width of corners
* @param unit Unit to use for size
*/
public DecoratorLayoutPanel(double size, Unit unit) {
this.setStyleName(DEFAULT_STYLENAME);
/* Container for center widget */
this.container = new LayoutPanel();
/* All inner widgets */
Widget topLeftInner = new HTML(" ");
Widget topCenterInner = new HTML(" ");
Widget topRightInner = new HTML(" ");
Widget middleLeftInner = new HTML(" ");
Widget middleCenterInner = this.container;
Widget middleRightInner = new HTML(" ");
Widget bottomLeftInner = new HTML(" ");
Widget bottomCenterInner = new HTML(" ");
Widget bottomRightInner = new HTML(" ");
/* Add to LayoutPanel */
super.add(topLeftInner);
super.add(topCenterInner);
super.add(topRightInner);
super.add(middleLeftInner);
super.add(middleCenterInner);
super.add(middleRightInner);
super.add(bottomLeftInner);
super.add(bottomCenterInner);
super.add(bottomRightInner);
/* Set default positioning - can override using CSS */
this.setWidgetLeftWidth(topLeftInner, 0, unit, size, unit);
this.setWidgetLeftRight(topCenterInner, size, unit, size, unit);
this.setWidgetRightWidth(topRightInner, 0, unit, size, unit);
this.setWidgetTopHeight(topLeftInner, 0, unit, size, unit);
this.setWidgetTopHeight(topCenterInner, 0, unit, size, unit);
this.setWidgetTopHeight(topRightInner, 0, unit, size, unit);
this.setWidgetLeftWidth(middleLeftInner, 0, unit, size, unit);
this.setWidgetLeftRight(middleCenterInner, size, unit, size, unit);
this.setWidgetRightWidth(middleRightInner, 0, unit, size, unit);
this.setWidgetTopBottom(middleLeftInner, size, unit, size, unit);
this.setWidgetTopBottom(middleCenterInner, size, unit, size, unit);
this.setWidgetTopBottom(middleRightInner, size, unit, size, unit);
this.setWidgetLeftWidth(bottomLeftInner, 0, unit, size, unit);
this.setWidgetLeftRight(bottomCenterInner, size, unit, size, unit);
this.setWidgetRightWidth(bottomRightInner, 0, unit, size, unit);
this.setWidgetBottomHeight(bottomLeftInner, 0, unit, size, unit);
this.setWidgetBottomHeight(bottomCenterInner, 0, unit, size, unit);
this.setWidgetBottomHeight(bottomRightInner, 0, unit, size, unit);
/* Set CSS Styles */
topLeftInner.setStyleName("topLeftInner");
topCenterInner.setStyleName("topCenterInner");
topRightInner.setStyleName("topRightInner");
middleLeftInner.setStyleName("middleLeftInner");
middleCenterInner.setStyleName("middleCenterInner");
middleRightInner.setStyleName("middleRightInner");
bottomLeftInner.setStyleName("bottomLeftInner");
bottomCenterInner.setStyleName("bottomCenterInner");
bottomRightInner.setStyleName("bottomRightInner");
this.getWidgetContainerElement(topLeftInner).setClassName("topLeft");
this.getWidgetContainerElement(topCenterInner).setClassName("topCenter");
this.getWidgetContainerElement(topRightInner).setClassName("topRight");
this.getWidgetContainerElement(middleLeftInner).setClassName("middleLeft");
this.getWidgetContainerElement(middleCenterInner).setClassName("middleCenter");
this.getWidgetContainerElement(middleRightInner).setClassName("middleRight");
this.getWidgetContainerElement(bottomLeftInner).setClassName("bottomLeft");
this.getWidgetContainerElement(bottomCenterInner).setClassName("bottomCenter");
this.getWidgetContainerElement(bottomRightInner).setClassName("bottomRight");
}
/**
* Set the center middle widget.
*
* @param widget The widget to add
*/
@Override
public void add(Widget widget) {
setOneWidget(widget);
}
/**
* Overloaded version for IsWidget.
*
* @see #add(Widget)
*/
public void add(IsWidget w) {
setWidget(w);
}
/**
* Set the center middle widget.
*
* @param w The widget to add
*/
@Override
public void setWidget(IsWidget w) {
setOneWidget(asWidgetOrNull(w));
}
private void setOneWidget(Widget w) {
// validate
if (w == widget) {
return;
}
// remove the old widget
if (widget != null) {
this.container.remove(widget);
}
// logical attach
widget = w;
if (w != null) {
this.container.add(w);
}
}
}