Search code examples
scrollbarvaadinpanel

How make scrollbar appear in Window with Panel with undefined size?


In the example bellow - window with Panel grows till it reaches browser window limits. After that Panel content becomes scrollable but no scrollbar appear. If I set Panel to fixed size scrollbar appear as per documentation.

Can someone suggest Vaadin pattern to implement scrollbars when Window or Panel size reaches browser window limit?

public class DemoUI extends UI {

@Override
protected void init(VaadinRequest vaadinRequest) {
    VerticalLayout layout = new VerticalLayout();
    layout.setSizeFull();
    Button demo1 = new Button("Question");
    demo1.addClickListener(new Button.ClickListener() {
        @Override
        public void buttonClick(Button.ClickEvent clickEvent) {
            Window window = new Window();
            window.setClosable(true);
            window.center();
            window.setResizable(true);
            window.setModal(false);
            window.setContent(new UndefWindow(window));

            addWindow(window);
        }
    });
    layout.addComponent(demo1);
    setContent(layout);
}
}

public class UndefWindow extends VerticalLayout {

private Window window;
public UndefWindow(Window window){
    this.window = window;
    Panel panel = new Panel();
    VerticalLayout layout = new VerticalLayout();
    Button add10 =new Button("Add 10");
    add10.addClickListener(new Button.ClickListener() {
        @Override
        public void buttonClick(Button.ClickEvent clickEvent) {
            for (int i=0; i <10; i++){
                layout.addComponent(new Label("Label: "+i));
            }
            window.center();
        }
    });
    layout.addComponent(add10);
    panel.setContent(layout);
    addComponent(panel);
    setExpandRatio(panel, 1.0f);

}
}

EDIT: I was able to achieve this with SizeReporter addon - code bellow

SizeReporter

public class UndefWindow extends VerticalLayout {

private Window window;
VerticalLayout root;
int rootHeight;
public UndefWindow(Window window, VerticalLayout root){
    this.window = window;
    this.root = root;

    Panel panel = new Panel();
 //   panel.setHeight("400px");

    SizeReporter sizeReporterRoot = new SizeReporter(root);
    sizeReporterRoot.addResizeListener(new ComponentResizeListener() {
        @Override
        public void sizeChanged(ComponentResizeEvent event) {
            System.out.println("Root size: " + event.getWidth() + " x " + event.getHeight());
            rootHeight = event.getHeight();
        }
    });
    SizeReporter sizeReporter = new SizeReporter(panel);
    sizeReporter.addResizeListener(new ComponentResizeListener() {
        @Override
        public void sizeChanged(ComponentResizeEvent event) {
            System.out.println("Panel size: " + event.getWidth() + " x " + event.getHeight());
            if(event.getHeight()>rootHeight){
                window.setHeight(rootHeight-60, Unit.PIXELS);
                //window.center();
                panel.setHeight(rootHeight-60, Unit.PIXELS);
            }else
                window.center();
        }
    });

    VerticalLayout layout = new VerticalLayout();

    Button add10 =new Button("Add 10");
    add10.addClickListener(new Button.ClickListener() {
        @Override
        public void buttonClick(Button.ClickEvent clickEvent) {
            for (int i=0; i <10; i++){
                layout.addComponent(new Label("Label: "+i));
            }
        }
    });
    addComponent(add10);
    panel.setContent(layout);
    addComponent(panel);

}
}

Solution

  • You have a bit overly complicated thinking in your Window content. In Vaadin, Window itself extends Panel, so you do not need additional Panel there at all. So I stripped it away. Also in order to layouts to work properly, you want to have your VerticalLayout height undefined, i.e. to grow until browser window size is met. In order to Panel scrolling to work in that scenario, there needs to be some content of defined height, in this case it is the Label, so I set defined height to Label. Then adding labels, will add size of the VerticalLayout, and once browser height is exceeded, Panel gets scroll bars.

    public class MyUI extends UI {
    
        @Override
        protected void init(VaadinRequest vaadinRequest) {
            VerticalLayout layout = new VerticalLayout();
            layout.setSizeFull();
            Button demo1 = new Button("Question");
            demo1.addClickListener(new Button.ClickListener() {
                @Override
                public void buttonClick(Button.ClickEvent clickEvent) {
                    Window window = new Window("Window");
                    window.setClosable(true);
                    window.center();
                    window.setResizable(true);
                    window.setModal(false);
                    window.setContent(new UndefWindow(window));
    
                    addWindow(window);
                }
            });
            layout.addComponent(demo1);
            setContent(layout);
        }
    
        public class UndefWindow extends VerticalLayout {
            private Window window;
            public UndefWindow(Window window){
                this.window = window;
                Button add10 =new Button("Add 10");
                add10.addClickListener(new Button.ClickListener() {
                    @Override
                    public void buttonClick(Button.ClickEvent clickEvent) {
                        for (int i=0; i <10; i++){
                            Label label = new Label("Label: "+i);
                            label.setHeight("38px");    
                            addComponent(label);
                        }
                        window.center();
                    }
                });
                addComponent(add10);
            }
        }
    }