public Thing(String name) {
      FlowPanel p = new FlowPanel();
      initWidget(p);

      setStyleName("thing");

      Button edit =
          new CssButton(
              "Edit",
              new ClickHandler() {
                public void onClick(ClickEvent event) {
                  new RowConstraintsDialog(getParentContainer(), Thing.this).display();
                }
              },
              "Edit constraints");

      Button delete =
          new CssButton(
              "Delete",
              new ClickHandler() {
                public void onClick(ClickEvent event) {
                  Container p = getParentContainer();
                  p.remove(Thing.this);
                  p.layout();
                }
              });

      FormBuilder b = new FormBuilder();
      b.add(edit, delete).colspan(4).endRow();
      b.field(new HTML("<b>" + name + "</b>")).endRow();
      b.label("Size")
          .field(size)
          .label("Weight")
          .field(weight)
          .label("Max size")
          .field(maxSize)
          .label("Overflow")
          .field(overflow)
          .endRow();
      b.label("Actual").field(actualSize).label("Extra").field(extraSize).endRow();
      p.add(b.getForm());
    }
  public RowLayoutPortlet() {
    LayoutPanel panel = new LayoutPanel();
    initWidget(panel);

    final CheckBox column = new CheckBox("Column");
    column.addValueChangeHandler(
        new ValueChangeHandler<Boolean>() {
          public void onValueChange(ValueChangeEvent<Boolean> event) {
            getTargetLayout().setColumn(column.getValue());
            target.layout();
          }
        });

    final TextBox spacing = new TextBox();
    spacing.setVisibleLength(4);
    spacing.addChangeHandler(
        new ChangeHandler() {
          public void onChange(ChangeEvent event) {
            try {
              getTargetLayout().setSpacing(Integer.parseInt(spacing.getText()));
            } catch (NumberFormatException e) {
              // ignore
            }
            target.layout();
          }
        });

    final Label bounds = new Label();
    target.addLayoutHandler(
        new LayoutHandler() {
          public void onLayoutUpdated(LayoutEvent layoutEvent) {
            bounds.setText(LDOM.getBounds(target).toString());
            column.setValue(getTargetLayout().isColumn());
            spacing.setText(Integer.toString(getTargetLayout().getSpacing()));
          }
        });

    demoList.addItem("Buttons & Body");
    demoList.addItem("Sidebar & Margin");
    demoList.addItem("Border Layout");
    demoList.setSelectedIndex(0);

    Button add =
        new CssButton(
            "Add Widget",
            new ClickHandler() {
              public void onClick(ClickEvent event) {
                target.add(new Thing("Widget-" + (target.getWidgetCount() + 1)));
                target.layout();
              }
            },
            "Add a new widget to the layout");

    final Button go =
        new CssButton(
            "Go",
            new ClickHandler() {
              public void onClick(ClickEvent event) {
                go();
              }
            },
            "Reset the layout to the selected state");

    demoList.addChangeHandler(
        new ChangeHandler() {
          public void onChange(ChangeEvent event) {
            go.click();
          }
        });

    FormBuilder b = new FormBuilder();
    b.add(add)
        .label("Spacing")
        .field(spacing)
        .field(column)
        .add("")
        .field(bounds)
        .wrap()
        .width("100%")
        .add(demoList)
        .add(go)
        .endRow();

    panel.add(b.getForm(), 22);
    panel.add(target, LayoutConstraints.HIDDEN);

    go();
  }