how to make the main window auto scrollable

I am trying to make the whole main window (Page) auto-scrollable. Basically, I have a main window with a VerticalLayout Then I have a tool bar with several buttons. Then I have a logo (a .jpg file). When user click on a button from the tool bar, a module will be added below the logo. My problem is that sometimes the browser doesn’t have a scroll bar on the side and it is very hard to get the whole content. Each module is a type of Layout.

some sample code I did:


public class App extends Application {
    public void init() {
		Window mainWindow = new Window("My Application");
		setMainWindow(mainWindow);
		VerticalLayout baseLayout = (VerticalLayout)mainWindow.getContent();
                HorizontalLayout topHl = createHead();                //this one creates toolbar and the logo
		baseLayout.addComponent(topHl);

                //here I assume I create a module and load it into the layout
                baseLayout.addComponent(addModule());
                
		getMainWindow().getContent().setSizeUndefined();       //I think this one equals to baseLayout.setSizeUndefined()
		getMainWindow().setContent(baseLayout);                
    }
}

I didn’t get the ideal result. The content is non-scrollable if the browser sizes to a smaller one(not enough to contain the whole content). I also try to add


mainWindow.setScrollable(true);

but it still doesn’t work.
Any help would be appreciated.

Thanks,
Bryan

Hi,

First, you’re right, these can be removed:

getMainWindow().getContent().setSizeUndefined();       //I think this one equals to baseLayout.setSizeUndefined()
getMainWindow().setContent(baseLayout);                

By looking at the rest of the code, I’d say the problem is in the layout of your module, not in the code shown here. For instance, if your module is 100% high, there will be no scrollbars, it will only fill the available space, clipping if there is overflow. But it’s hard to say without more code.

One thing you can do is analyze layouts, which is available in the debug window (add ?debug to the url).

Best Regards,
Marc

Hi Marc,

Thank you very much for your reply.

I used the debug mode you suggested. When I perform a analyze layouts, I got the following info:

Running layout functions due window resize
Making UIDL Request with params: 168971
Server visit took 7ms
JSON parsing took 1ms

change format=uidl pid=PID0
com.vaadin.terminal.gwt.client.ui.VView id=PID0 caption=Creditlime Application name=2061281513 theme=creditlime resizable=true main=true
variables

scrollLeft=0
scrollTop=0
positionx=-1
positiony=-1
close=false
com.vaadin.terminal.gwt.client.ui.VVerticalLayout id=PID43 margins=15 alignments={} expandRatios={}
com.vaadin.terminal.gwt.client.ui.VHorizontalLayout id=PID44 margins=0 alignments={} expandRatios={}
com.vaadin.terminal.gwt.client.ui.VVerticalLayout id=PID45 margins=0 alignments={PID46:33,PID54:48,PID53:48,} expandRatios={}
com.vaadin.terminal.gwt.client.ui.VHorizontalLayout id=PID46 style=toolbar margins=0 alignments={} expandRatios={}
com.vaadin.terminal.gwt.client.ui.VButton
com.vaadin.terminal.gwt.client.ui.VButton
com.vaadin.terminal.gwt.client.ui.VButton
com.vaadin.terminal.gwt.client.ui.VButton
com.vaadin.terminal.gwt.client.ui.VButton
com.vaadin.terminal.gwt.client.ui.VButton
com.vaadin.terminal.gwt.client.ui.VEmbedded id=PID53 caption= type=image src=theme://images/creditlime_web.jpg mimetype=image/jpeg
com.vaadin.terminal.gwt.client.ui.VHorizontalLayout id=PID54 style=search margins=15 alignments={PID55:48,} expandRatios={}
com.vaadin.terminal.gwt.client.ui.VTextField
com.vaadin.terminal.gwt.client.ui.VButton


Layouts analyzed on server, total top level problems: 1

Root problems

VHorizontalLayout id: PID44
Height problem: Component with relative height inside a VerticalLayout with no height defined.
Width problem:
At least one of a VerticalLayout’s components must have non relative width if the width of the layout is not defined

Emphasis component in UI
Expand this node to show problems that may be dependent on this problem.
VVerticalLayout id: PID45
Width problem: Component with relative width inside a HorizontalLayout with no width defined
Emphasis component in UI


Processing time was 32ms for 2872 characters of JSON
Referenced paintables: 14
Removed variable from removed component: PID0
Removed variable from removed component: PID0

I don’t quite understand what is “non relative width.” Could you help me with that.

Do I have to set at least one layout with .setSizeFull();

How do I fix that.

Thanks,

Bryan

Non relative width essentially means a component inside the VerticalLayout needs to have a fixed width in pixels or be undefined wide (also called auto sometimes). It cannot be 100% (relative) as there is nothing that defines the size of the parent layout. My guess would be that your VHorizontalLayout (PID44) is set to 100% width while its parent VVerticalLayout (PID45) is set to undefined width

As undefined width for a layout means it uses the size of its children and 100% for a child means it uses the size of its parent, you won’t get any sensible result unless you change one of them (hence the problems by analyze layouts).

Thanks, Artur,

I have further questions based on your answer. How to quickly locate the layout that contains this problem. For instance, it gave me this PID44 and PID45, is there a way I can find the exact layout based on these identities.

For solving problem, should I add something like lo.setWidth(400, UNITS_PIXELS); and also comment out //lo.setWidth(100%); . When I rerun the debug, there is no root problem, however, the scrollbar is still not showing up. I am really confused.

My main layout in the main window is VerticalLayout, i will just call it vl.

in vl, I will have different modules. Some are HroizontalLayout, some are FormLayout, some are VerticalLayout. all theses modules will be added or removed based on different events. Inside each module, there might be another layout in it. For example, in my code, I have a head module which is a VerticalLayout(I will name it as headVl), then in this layout, I have a toolbar, which is a HorizontalLayout, and a Logo .jpg file as an Embed, a search bar as a HorizontalLayout. This whole module will stay in the mainWindow at all time. Then based on different button clicks, different modules will be loaded to the main VerticalLayout lo.

In my code, I never use any .setSizeFull() or setWidth(100%) now. I used one .setWidth(400, UNITS_PIXELS); in toolbar module. Say I think toolbar’s parent will be the VerticalLayout headVl. and its “grandparent” will be this VerticalLayout lo.

If necessary, I can attach most of my code to solve this scrollable problem. I try to play with the .CSS file and it will display a scroll bar in IE but not in Chrome or Firefox and I don’t think it is a good way to solve that problem.

Again, thanks for any help.

Bryan

One way is too look at the hierarchy. VerticalLayout (PID43) is the layout you set as the main window content. HorizontalLayout (PID44) is the layout you have added to that main window layout and VerticalLayout (PID45) again has been added to that layout (provided I read your paste correctly).

How you should solve it depends on how you want your layouts to work. If you want the layout to use all available space (horizontally) in the window you should set its width to 100% and ensure that also its parents’ width is set to 100%.If you want the layout to always use 400 pixels you should set its width to 400 pixels like in your code above.

You should be aware of that layouts in Vaadin won’t ever add scrollbars, instead they will clip the contents. Window and Panel on the other hand add scrollbars if the content is larger than the Window/Panel. Your layout sounds like a typical application where you want a main layout with a toolbar and other stuff and then a scrollable main area. One way to accomplish this is to add a panel that uses the available space in the main layout and then switch the contents of the panel according to what module should be visible. If the module is larger than the Panel, scrollbars will be shown automatically. If the content is smaller (or set to 100%x100% e.g. using setSizeFull()), no scrollbars will be visible

Playing with CSS to enable scrollbars is typically a very bad idea.

Thanks,

I understand that the Layout won’t be able to be scrollable itself. But all our applications are started with a Window right? so The window should be scrollable when I put all the Layout in this window and the content exceeds the border of browser. However, mine is not scrollable. The page (the whole window) is static and not able to scroll. I ensured that in my Window there is no setSizeFull() or setHeight(100%) in any layout(or panel, window). I think that is the only cause for my window not to be scrollable vertically.

Bryan

Not sure as I’m mostly a beginner, too, but I found that if I put my contents into the (default) VerticalLayout that comes with a Panel, and add the Panel to my Window, scrollbars appear, so we have code like this:

        Window w = new Window("Window title");
        w.setWidth(100, UNITS_PERCENTAGE);
        w.setHeight(100, UNITS_PERCENTAGE);
        
        Panel windowPanel = new Panel();
        windowPanel.setSizeFull();
        windowPanel.setScrollable(true);
        VerticalLayout panelLayout = (VerticalLayout)windowPanel.getContent();
        panelLayout.setWidth(100, UNITS_PERCENTAGE);
        panelLayout.setMargin(false);
        panelLayout.setSpacing(false);
        
        panelLayout.addComponent(form); // sample adds a Form component, but should be anything you want
        w.setContent(windowPanel);

Hope that helps…