I'm trying to build a panel that offers vertical scrollbars as needed. I've managed to do it before but this required so much weird coding and direct access of Style objects that I assume I must have been doing it wrong. When I build this the Layouts go off the page (see picture). I'm not sure why this is. If you see the picture the GroupCheckBoxPanel (the main class in this particular case) it has correctly built its FieldSets and Buttons from the provided GroupEntry but there are no Scrollbars. What triggers the system to add Scrollbars? I'm sure there's a simple approach I just keep overlooking.

I'm tried to provide a runnable version of the code I'm working with but I had to make some inline modifications to pull out the complicated class hierarchy parts. The main widget I'm working with is the GroupCheckBoxPanel.


jobs.jpg


Code:
/**
 * See also CheckBoxPanel
 * 
 * This class behaves similar to CheckBoxPanel but in addition it groups the options by a header
 * @author LENOVO USER
 *
 */
public class GroupCheckBoxPanel extends CssFloatLayoutContainer
{
    List<ParameterButton> boxes;
    private TextButton saveBtn;
    public GroupCheckBoxPanel(String name, List<GroupEntry> list)
    {
        boxes = new ArrayList<ParameterButton>();
        if(list != null)
            init(name, list);
        //this.setHeaderVisible(false);
        //this.setBodyBorder(false);
    }
    
    public GroupCheckBoxPanel(String name, List<GroupEntry> list, TextButton b)
    {
        saveBtn = b;
        boxes = new ArrayList<ParameterButton>();
        if(list != null)
            init(name, list);
        //this.setHeaderVisible(false);
        //this.setBodyBorder(false);
    }


    
    public void init(String name, List<GroupEntry> list)
    {
        this.clear();
        this.setStyleFloat(Style.Float.LEFT);
        ScrollSupport support = this.getScrollSupport();
        support.ensureVisible(saveBtn);
        for(int x = 0; x < list.size(); x++)
        {
            if(list.get(x).getEntries().size() == 0)
                continue;
            FieldSet set = new FieldSet();
            set.setHeadingText(list.get(x).getName());
            set.setCollapsible(false);
            CssFloatLayoutContainer vlc = new CssFloatLayoutContainer();
            set.add(vlc);
            
            for(int y = 0; y < list.get(x).getEntries().size(); y++)
            {
                
                Entry e = list.get(x).getEntries().get(y);
                ScaleBaseFormItem boxItem = new ScaleBaseFormItem();
                boxItem.setName(e.getDisplay());
                boxItem.setType(ScaleBaseFormType.BOOLEAN);
                ParameterButton box = (ParameterButton)ScaleBaseFormLayout.createGenericWidgit(boxItem, true);
                box.setId(name +"-"+e.getId());
                setAttributes(box);            
                boxes.add(box);
                
                ScaleBaseFormLayout layout = new ScaleBaseFormLayout(boxItem, true);
                vlc.add(layout,new CssFloatData(1));
            }
            add(set, new CssFloatData(1));
        }
    }
    
    public List<ParameterButton> getBoxes()
    {
        return boxes;
    }
    
    public void setAttributes(ParameterButton box)
    {
        
    }
    
    public long getMask()
    {
           long total = 0;
            for(int x = 0; x < getBoxes().size(); x++)
            {
                if(getBoxes().get(x).getValue())
                {
                    String idString = getBoxes().get(x).getId();
                    int id = Integer.parseInt(idString.substring(idString.indexOf("-")+1, idString.length()));
                    total += Math.pow(2, id-1);
                }
            }
            return total;       
    }
    
    public void setMask(long mask)
    {
        for(int x = 0; x < getBoxes().size(); x++)
        {
            String idString = getBoxes().get(x).getId();
            int id = Integer.parseInt(idString.substring(idString.indexOf("-")+1, idString.length()));
            
            int bitMask = (int)Math.pow(2, id-1);
            
            long value = mask & bitMask;
            if( (mask & bitMask) == bitMask)
                getBoxes().get(x).setValue(true);
            else
                getBoxes().get(x).setValue(false);
        }
    }
    
public void onChangeCheckBox()
{

        //if(panel.isValid(true))
        //    saveBtn.enable();
        //else
            //saveBtn.disable();

}
Code:
public class ParameterButton extends IconButton
{
    private Parameter p;
    private boolean value;

    public ParameterButton(Parameter ph) 
    {
        super("foo");
        this.p = ph;
        if(ph.getValue().equals("1"))
            value = true;
        else
            value = false;
        //value = Boolean.parseBoolean(p.getValue());
        this.addSelectHandler(new SelectHandler(){

            @Override
            public void onSelect(SelectEvent event) 
            {
                value = !value;
                update(value);
                p.setModified(true);
            }});
        this.update(value);
    }
    
    public ParameterButton(boolean b)
    {
        super("foo");
        this.p = null;
        value = b;
        this.addSelectHandler(new SelectHandler(){

            @Override
            public void onSelect(SelectEvent event) 
            {
                value = !value;
                update(value);
                if(p != null)
                 p.setModified(true);
            }});
        this.update(b);
    }
    
    public ParameterButton()
    {
        super("foo");
        this.p = null;
        value = false;
        this.addSelectHandler(new SelectHandler(){

            @Override
            public void onSelect(SelectEvent event) 
            {
                value = !value;
                update(value);
                if(p != null)
                 p.setModified(true);
            }});
        this.update(false);
    }
    
    public void update(boolean value)
    {
        if(p != null)
            this.p.setValue(""+value);
        this.value = value;
        this.removeStyleName(this.getStyleName());
        if(value)
        {
            this.changeStyle("parameterButtonOn");
        }
        else
        {
            this.changeStyle("parameterButtonOff");
        }
    }
    
    public boolean isValue() {
        return value;
    }

    public boolean getValue() {
        return value;
    }
    
    public void setValue(boolean v) {
        update(v);
    }

}
Code:
package com.scalebase.management.client.base.form;

import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
//import com.scalebase.management.client.base.BaseEditWindow;
import com.scalebase.management.client.model.ParameterButton;
import com.sencha.gxt.cell.core.client.form.ComboBoxCell.TriggerAction;
import com.sencha.gxt.core.client.util.Margins;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.form.ComboBox;
import com.sencha.gxt.widget.core.client.form.FieldLabel;
import com.sencha.gxt.widget.core.client.form.NumberField;
import com.sencha.gxt.widget.core.client.form.NumberPropertyEditor;
import com.sencha.gxt.widget.core.client.form.PasswordField;
import com.sencha.gxt.widget.core.client.form.TextField;
import com.sencha.gxt.widget.core.client.form.validator.MaxLengthValidator;
import com.sencha.gxt.widget.core.client.form.validator.MaxLengthValidator.MaxLengthMessages;
import com.sencha.gxt.widget.core.client.form.validator.MaxNumberValidator;
import com.sencha.gxt.widget.core.client.form.validator.MinNumberValidator;

/**
 * Utility class which creates a panel from a given ScaleBaseFormItem
 * this panel contains the specificed fieldlabel and formItem. 
 * We use this class to consolidate all visual components (styles, padding, align, etc) which may
 * not be done as easily in CSS into one place to be easily modified
 * @author LENOVO USER
 *
 */
public class ScaleBaseFormLayout extends VerticalLayoutContainer
{
    private FieldLabel name;
    private FieldLabel desc;
    public ScaleBaseFormLayout(ScaleBaseFormItem item, boolean isPopup)
    {    
        if(item.getWidgit() != null)
            init(item, item.getWidgit().asWidget(), isPopup);
        else
            init(item, null, isPopup);
    }
    
    /*public ScaleBaseFormLayout(BaseEditWindow edit, ScaleBaseFormItem item, boolean isPopup)
    {    
        if(item.getWidgit() != null)
            init(edit, item, item.getWidgit().asWidget(), isPopup);
        else
            init(edit, item, null, isPopup);
    }*/
    
    public ScaleBaseFormLayout(String baseName, ScaleBaseFormItem item, boolean isPopup)
    {        
        init(baseName, item, item.getWidgit().asWidget(), isPopup);
    }
    
    public void init(ScaleBaseFormItem item, Widget w, boolean isPopup)
    {
        init("", item, w, isPopup);
    }
    
    /*public void init(BaseEditWindow win, ScaleBaseFormItem item, Widget w, boolean isPopup)
    {
        if(win.getName() != null)
            init(win.getName(), item, w, isPopup);
        else
            init("", item, w, isPopup);
    }*/
    
    public void init(String baseName, ScaleBaseFormItem item, Widget w, boolean isPopup)
    {    
        Margins margin = new Margins();
        margin.setTop(10);
        margin.setBottom(10);
        margin.setLeft(10);
        margin.setRight(10);
        String isPopupStyle = "";
        if(isPopup)
            isPopupStyle = "Popup";
        if(item.getName() != null && item.getName().trim().length() != 0)
        {
            if(item.getWidgit() != null)
                name = new FieldLabel(item.getWidgit().asWidget());
            else
                name = new FieldLabel();
            name.setLabelSeparator("");
            //the first setStyleName overwrites the GWT defaults. after that we layer more styles 
            name.setStyleName("componentFormName"+isPopupStyle);
            //name.addStyleName("componentFormName"+isPopupStyle);
            name.addStyleName("componentForm"+isPopupStyle);
            if(item.getWidgit() == null)
                name.addStyleName("FieldLabelNoWidget");
            name.addStyleName(collapseString(baseName + item.getName())+"componentFormName"+isPopupStyle);
            name.setText(item.getName());                
            name.setLabelPad(item.getLabelPadding());
            if(isPopup)
                name.setLabelWidth(item.getLabelWidthPopup());
            else
                name.setLabelWidth(item.getLabelWidth());
            if(item.isRequired())
            {
                name.setText(name.getText() + "*");
            }
            if(item.isVisible() == false)
            {
                name.setVisible(false);
                if(w != null)
                    w.setVisible(false);
            }
            

            
            margin.setBottom(0);
            add(name, new VerticalLayoutData(-1, -1, margin));
        }
        
        if(item.getDescription() != null && item.getDescription().trim().length() != 0)
        {
            desc = new FieldLabel();
            desc.setLabelSeparator("");
            //the first setStyleName overwrites the GWT defaults. after that we layer more styles 
            desc.setStyleName("componentFormDesc"+isPopupStyle);
            desc.addStyleName("componentForm"+isPopupStyle);
            if(item.getWidgit() == null)
                desc.addStyleName("FieldLabelNoWidget");
            desc.addStyleName(collapseString(baseName+item.getDescription())+"componentFormDesc"+isPopupStyle);
            desc.setText(item.getDescription());
            desc.setLabelPad(item.getDescPadding());
            if(isPopup)
                desc.setLabelWidth(item.getDescWidthPopup());
            else
                desc.setLabelWidth(item.getDescWidth());
            margin.setTop(0);
            margin.setLeft(20);
            if(item.isVisible() == false)
                desc.setVisible(false);
            add(desc, new VerticalLayoutData(-1, -1, margin));
        }
    }
    
    public static void applyNameStyles(FieldLabel name, String baseName, String itemName, boolean isPopup)
    {
        String isPopupStyle = "";
        if(isPopup)
            isPopupStyle = "Popup";
        name.addStyleName("componentFormName"+isPopupStyle);
        name.addStyleName("componentForm"+isPopupStyle);
        name.addStyleName(collapseString(baseName + itemName)+"componentFormName"+isPopupStyle);
    }
    
    public static void applyDescStyles(FieldLabel name, String baseName, String itemName, boolean isPopup)
    {
        String isPopupStyle = "";
        if(isPopup)
            isPopupStyle = "Popup";
        name.addStyleName("componentFormDesc"+isPopupStyle);
        name.addStyleName("componentForm"+isPopupStyle);
        name.addStyleName(collapseString(baseName + itemName)+"componentFormDesc"+isPopupStyle);
    }
    
    public static String collapseString(String s)
    {
        if(s != null)
            return s.replaceAll("\\s", "");
        return null;
    }
    
    /*public static IsWidget createGenericWidget(BaseEditWindow edit, ScaleBaseFormItem item, boolean isPopup)
    {
        if(edit.getName() == null)
            return createGenericWidgit("", item, isPopup);
        else
            return createGenericWidgit(edit.getName(), item, isPopup);
    }*/

    public static IsWidget createGenericWidgit(ScaleBaseFormItem item, boolean isPopup)
    {
        return createGenericWidgit("", item, isPopup);
    }
    
    public static IsWidget createGenericWidgit(String baseName, ScaleBaseFormItem item, boolean isPopup)
    {
        String isPopupStyle = "";
        if(isPopup)
            isPopupStyle = "Popup";
        
        IsWidget w = null;
        if(item.getType() == ScaleBaseFormType.INTEGER)
        {
            NumberField<Integer> nf = new NumberField<Integer>(new NumberPropertyEditor.IntegerPropertyEditor());
            if(isPopup)
                nf.setWidth(item.getWidgetWidthPopup());
            else
                nf.setWidth(item.getWidgetWidth());
            nf.addStyleName("intNumberField"+isPopupStyle);
            nf.addStyleName("NumberField"+isPopupStyle);
            nf.addStyleName(collapseString(baseName + item.getName())+"numberField"+isPopupStyle);
            nf.setAllowBlank(!item.isRequired());
            if(item.getMaxNumber() != null)
            {
                MaxNumberValidator mnv = new MaxNumberValidator(item.getMaxNumber());
                nf.addValidator(mnv);
            }
            
            if(item.getMinNumber() != null)
            {
                MinNumberValidator mnv = new MinNumberValidator(item.getMinNumber());
                nf.addValidator(mnv);
            }
            w = nf;
        }
        else if(item.getType() == ScaleBaseFormType.DOUBLE)
        {
            NumberField<Double> nf = new NumberField<Double>(new NumberPropertyEditor.DoublePropertyEditor());
            if(isPopup)
                nf.setWidth(item.getWidgetWidthPopup());
            else
                nf.setWidth(item.getWidgetWidth());
            nf.addStyleName("doubleNumberField"+isPopupStyle);
            nf.addStyleName("NumberField"+isPopupStyle);
            nf.addStyleName(collapseString(baseName+item.getName())+"numberField"+isPopupStyle);
            nf.setAllowBlank(!item.isRequired());
            if(item.getMaxNumber() != null)
            {
                MaxNumberValidator mnv = new MaxNumberValidator(item.getMaxNumber());
                nf.addValidator(mnv);
            }
            
            if(item.getMinNumber() != null)
            {
                MinNumberValidator mnv = new MinNumberValidator(item.getMinNumber());
                nf.addValidator(mnv);
            }
            
            w = nf;
        }
        else if(item.getType() == ScaleBaseFormType.BOOLEAN)
        {
            ParameterButton nf = new ParameterButton();
            nf.addStyleName("booleanField"+isPopupStyle);
            nf.addStyleName(collapseString(baseName+item.getName())+"booleanField"+isPopupStyle);
            //nf.setAllowBlank(!item.isRequired());
            w = nf;
        }
        else if(item.getType() == ScaleBaseFormType.STRING)
        {
            TextField nf = new TextField();
            if(isPopup)
                nf.setWidth(item.getWidgetWidthPopup());
            else
                nf.setWidth(item.getWidgetWidth());
            nf.addStyleName("TextField"+isPopupStyle);
            nf.addStyleName(collapseString(baseName+item.getName())+"textField"+isPopupStyle);
            nf.setAllowBlank(!item.isRequired());
            if(item.getMaxCharacters() > 0)
            {
                MaxLengthValidator maxLength = new MaxLengthValidator(item.getMaxCharacters());
                nf.addValidator(maxLength);
                
            }
            w = nf;
        }
        else if(item.getType() == ScaleBaseFormType.PASSWORD)
        {
            PasswordField nf = new PasswordField();
            if(isPopup)
                nf.setWidth(item.getWidgetWidthPopup());
            else
                nf.setWidth(item.getWidgetWidth());
            nf.addStyleName("PasswordField"+isPopupStyle);
            nf.addStyleName(collapseString(baseName + item.getName())+"passwordField"+isPopupStyle);
            nf.setAllowBlank(!item.isRequired());
            if(item.getMaxCharacters() > 0)
            {
                MaxLengthValidator maxLength = new MaxLengthValidator(item.getMaxCharacters());
                nf.addValidator(maxLength);
                
            }
            w = nf;
        }
        
        
        
        item.setWidgit(w);
        return w;
    }
    
    
    
    public static IsWidget createGenericWidget(ScaleBaseComboItem item, boolean isPopup)
    {
        return createGenericWidget("", item, isPopup);
    }
    /*public static IsWidget createGenericWidget(BaseEditWindow win, ScaleBaseComboItem item, boolean isPopup)
    {
        if(win.getName() != null)
            return createGenericWidget(win.getName(), item, isPopup);
        else
            return createGenericWidget("", item, isPopup);        
    }*/
    
    public static IsWidget createGenericWidget(String baseName, ScaleBaseComboItem item, boolean isPopup)
    {
        String isPopupStyle = "";
        if(isPopup)
            isPopupStyle = "Popup";
        IsWidget w = null;
        if(item.getType() == ScaleBaseFormType.REFERENCE)
        {
            ListStore store = new ListStore(item.getModel());
            ComboBox combo = new ComboBox(store, item.getLabel());
            combo.addStyleName("comboField"+isPopupStyle);
            combo.addStyleName(collapseString(baseName+item.getName())+"comboField"+isPopupStyle);
            combo.setTriggerAction(TriggerAction.ALL);
            if(item.isRequired())
                combo.setAllowBlank(false);            
            w = combo;
        }
        item.setWidgit(w);
        return w;
    }
    
    public static FieldLabel createGenericFieldLabel(String baseName, ScaleBaseFormItem item, boolean isPopup)
    {
        IsWidget w = createGenericWidgit(baseName, item, isPopup);
        item.setWidgit(w);
        
        FieldLabel name = null;
        if(item.getName() != null && item.getName().trim().length() != 0)
        {
            if(item.getWidgit() != null)
                name = new FieldLabel(item.getWidgit().asWidget());
            else
                name = new FieldLabel();
            name.setLabelSeparator("");
            
            name.setText(item.getName());                
            name.setLabelPad(item.getLabelPadding());
            name.setLabelWidth(item.getLabelWidth());            
        }
        item.setWidgit(name);
        return name;
    }

    public FieldLabel getName() {
        return name;
    }

    public FieldLabel getDesc() {
        return desc;
    }
    
    
}
Code:

import com.google.gwt.user.client.ui.IsWidget;

/**
 * Pojo used to abstract away FieldItem creation
 * @author LENOVO USER
 *
 */
public class ScaleBaseFormItem 
{
    private boolean required;  //must the valid be filed in for the form to be valid
    private String name;  //form name (actually its the field title more than the name. The text visible next to it)
    private String description; //the text visible underneath the field item in a smaller font
    private IsWidget widgit;  //holds the widgit associated with the fieldLabel
    private int maxCharacters;
    private Double maxNumber;
    private Double minNumber;
    //so far, these are only used for fields
    private int WidgetWidth;
    private int WidgetWidthPopup;
    
    private ScaleBaseFormType type;
    private int LabelPadding;
    private int LabelWidth;
    private int LabelWidthPopup;
    private int DescPadding;
    private int DescWidth;
    private int DescWidthPopup;
    
    private boolean visible;
    
    public ScaleBaseFormItem()
    {
        
        //label widths should be desc Widths - padding
        visible = true;
        LabelPadding = 10;
        LabelWidth = 290;
        DescPadding = 200;
        DescWidth = 300;
        LabelWidthPopup = 190;
        DescWidthPopup = 200;
        WidgetWidth = 400;
        WidgetWidthPopup = 300;
    }
    
    
    
    public boolean isVisible() {
        return visible;
    }



    public void setVisible(boolean visible) {
        this.visible = visible;
    }



    public int getLabelPadding() {
        return LabelPadding;
    }
    public void setLabelPadding(int labelPadding) {
        LabelPadding = labelPadding;
    }
    public int getLabelWidth() {
        return LabelWidth;
    }
    public void setLabelWidth(int labelWidth) {
        LabelWidth = labelWidth;
    }
    public int getDescPadding() {
        return DescPadding;
    }
    public void setDescPadding(int descPadding) {
        DescPadding = descPadding;
    }
    public int getDescWidth() {
        return DescWidth;
    }
    public void setDescWidth(int descWidth) {
        DescWidth = descWidth;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    
    

    public IsWidget getWidgit() {
        return widgit;
    }
    public void setWidgit(IsWidget widgit) {
        this.widgit = widgit;
    }

    public ScaleBaseFormType getType() {
        return type;
    }
    public void setType(ScaleBaseFormType type) {
        this.type = type;
    }
    public boolean isRequired() {
        return required;
    }
    public void setRequired(boolean required) {
        this.required = required;
    }



    public int getLabelWidthPopup() {
        return LabelWidthPopup;
    }



    public void setLabelWidthPopup(int labelWidthPopup) {
        LabelWidthPopup = labelWidthPopup;
    }



    public int getDescWidthPopup() {
        return DescWidthPopup;
    }



    public void setDescWidthPopup(int descWidthPopup) {
        DescWidthPopup = descWidthPopup;
    }



    public int getWidgetWidth() {
        return WidgetWidth;
    }



    public void setWidgetWidth(int widgetWidth) {
        WidgetWidth = widgetWidth;
    }



    public int getWidgetWidthPopup() {
        return WidgetWidthPopup;
    }



    public void setWidgetWidthPopup(int widgetWidthPopup) {
        WidgetWidthPopup = widgetWidthPopup;
    }



    public int getMaxCharacters() {
        return maxCharacters;
    }



    public void setMaxCharacters(int maxCharacters) {
        this.maxCharacters = maxCharacters;
    }



    public Double getMaxNumber() {
        return maxNumber;
    }



    public void setMaxNumber(double maxNumber) {
        this.maxNumber = maxNumber;
    }



    public Double getMinNumber() {
        return minNumber;
    }



    public void setMinNumber(double minNumber) {
        this.minNumber = minNumber;
    }
    
    
    
}
Code:

import java.io.Serializable;

import com.google.gwt.user.client.rpc.IsSerializable;

public class Entry implements Serializable, IsSerializable 
{
    private String id;
    private String display;
    
    public Entry()
    {
        
    }
    
    public Entry(String id, String display)
    {
        this.id = id;
        this.display = display;
    }
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getDisplay() {
        return display;
    }
    public void setDisplay(String display) {
        this.display = display;
    }
    
    
    
}
Code:
import java.util.List;

import com.scalebase.api.dto.Entry;

public class GroupEntry 
{
    private String name;
    private int id;
    private List<Entry> entries;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public List<Entry> getEntries() {
        return entries;
    }
    public void setEntries(List<Entry> entries) {
        this.entries = entries;
    }
    
    
}