Subwindow won't resize to capture the inner elements

I have made Dialog class where I can pass in components and it should build the grid layout with buttons. However, subwindow is always smaller than the real components inside. If I set the subwindow to setSizeFull, it takes whole screen, which I do not want.

Here is my dialog.create method. I am not sure what to do anymore…

    @Override
    @SuppressWarnings("serial")
    public void create(AbstractComponent root) throws Exception {
        log.debug("Opening new dialog " + this);

        window = new Window("");
        parent = root.getWindow();

        grid = new GridLayout();
        grid.setSpacing(true);
        grid.setColumns(2);
        grid.setColumnExpandRatio(0, 1);
        grid.setColumnExpandRatio(1, 3);
        grid.insertRow(0);
        grid.setSizeFull();
        
        gridLine = 0;
        
        createWidgets(grid);
        
        errors.clear();  
       
        Button okButton = new Button("OK");
        okButton.addListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                if (saveModel()) {
                    closeWindow();
                    afterOK.run();
                } else
                    checkMarks();
            }

        });

        Button cancelButton = new Button("Zrušit");
        cancelButton.addListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                closeWindow();
                afterCancel.run();
            }

        });

        loadModel();
        
        grid.addComponent(cancelButton, 0, gridLine, 0, gridLine);
        grid.addComponent(okButton, 1, gridLine, 1, gridLine);
        
        parent.addWindow(window);
        window.addComponent(grid);
        window.setCaption(name);
        window.setSizeUndefined();
        window.setModal(true);
        window.setClosable(false);
        window.center();
    }

Okay, it is only the width that is acting weird, height stretch correctly.

Seems you have a full-sized GridLayout in an undefined-sized window - this is an invalid layout configuration. If you set the GridLayout to undefined size, it should fix the issue and make the layout and window expand as the content requires.

Note: this assumes that the content in your GridLayout also has non-relative sizes.

Here is my whole class:

public abstract class CEDialogBase implements CEDialog, Dialog {
    private static final Logger log = Logger.getLogger(CEDialogBase.class);
    protected static final Runnable empty = new Runnable() {
        @Override
        public void run() { }
    };
    
    private Window window;
    private final Runnable afterOK, afterCancel;
    private Map<AbstractComponent, Label> labelMap =
            new HashMap<AbstractComponent, Label>();
    private List<Label> widgets = new ArrayList<Label>();
    private List<Label> errors = new ArrayList<Label>();    
    private String name;
    
    public CEDialogBase(String name, Runnable afterOK2, Runnable afterCancel2) {
        this.afterOK = afterOK2;
        this.afterCancel = afterCancel2;
        this.name = name;
    }
    
    protected Long modelId = null;

    @Override
    public CEDialog setModel(Long id) {
        modelId = id;
        return this; // for subcalls
    }
    
    private Window parent;
    private GridLayout grid;
    private int gridLine;
    
    @Override
    @SuppressWarnings("serial")
    public void create(AbstractComponent root) throws Exception {
        log.debug("Opening new dialog " + this);

        window = new Window("");
        parent = root.getWindow();

        grid = new GridLayout();
        grid.setSpacing(true);
        grid.setColumns(2);
        grid.setColumnExpandRatio(0, 1);
        grid.setColumnExpandRatio(1, 3);
        grid.setSizeUndefined();
        
        gridLine = 0;
        
        createWidgets(grid);
        
        errors.clear();  
       
        Button okButton = new Button("OK");
        okButton.addListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                if (saveModel()) {
                    closeWindow();
                    afterOK.run();
                } else
                    checkMarks();
            }

        });

        Button cancelButton = new Button("Zrušit");
        cancelButton.addListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                closeWindow();
                afterCancel.run();
            }

        });

        loadModel();
        
        cancelButton.setSizeUndefined();
        okButton.setSizeUndefined();
        
        grid.addComponent(cancelButton, 0, gridLine, 0, gridLine);
        grid.addComponent(okButton, 1, gridLine, 1, gridLine);
        
        parent.addWindow(window);
        window.addComponent(grid);
        window.setCaption(name);
        window.setSizeUndefined();
        window.setModal(true);
        window.setClosable(false);
        window.center();
    }
    
    private void checkMarks() {
        for (AbstractComponent ac : widgets)
            ac.removeStyleName(Utils.ERROR_STYLE);
        
        for (AbstractComponent ac : errors)
            ac.addStyleName(Utils.ERROR_STYLE);
        
        errors.clear();
    }

    /**
     * Used for subclass to create the layout
     * @param layout
     */
    protected abstract void createWidgets(GridLayout layout);
    
    protected Label registerWidget(AbstractComponent valueWidget){
        return registerWidget(valueWidget, 1);
    }
    
    protected Label registerWidget(AbstractComponent valueWidget, int gridValue){
        Label label = new Label();

        int gc = gridValue;
        do {
            --gc;
            grid.insertRow(gridLine);
        } while (gc > 0);
        
        
        grid.addComponent(label, 0, gridLine, 0, gridLine);
        grid.setComponentAlignment(label, Alignment.TOP_RIGHT);
        grid.addComponent(valueWidget, 1, gridLine, 1, gridLine+gridValue-1);
        grid.setComponentAlignment(valueWidget, Alignment.TOP_LEFT);
        
        gc = gridValue;
        do {
            --gc;
            ++gridLine;
        } while (gc > 0);
        
        widgets.add(label);
        labelMap.put(valueWidget, label);
        
        label.setSizeUndefined();
        valueWidget.setSizeUndefined();
        
        return label;
    }

    private void closeWindow() {
        parent.removeWindow(window);
    }

    @Override
    public final boolean saveModel() {
        if (!checkConditions())
            return false;

        saveModel(modelId);
        return true;
    }

    protected abstract void saveModel(Long modelId);
    
    protected void markError(AbstractComponent ac){
        errors.add(labelMap.get(ac));
    }
}

The only way widgets are inserted into this class is via registerWidget, where sizes are set to undefined for everything. However, still, the width of subwindow only shows the labels in the grid, not the rest and I have to resize manualy.

Ah, didn’t realize that this was in Vaadin 6. In that version there’s a default content within each window (a VerticalLayout) and it’s width is 100% which probably causes your problem.

On line 89 try calling “window.setContent(grid);” instead of “window.addComponent(grid);”. This should fix the issue.

Awesome, that helped! Thanks a lot!