0
votes

I'm trying to use a ScrollPanel of GWT in a page. Since most of the contents are in the ScrollPanel, I want it to take an as-large-as-possible part of the page and resize as the page may resize. Naturally I would want to set it a relative size, i.e. setSize("100%","100%"). However the document says it can only be set a size in absolute CSS units (e.g. "10px", "1em", but not "50%")

I cannot understand why ScrollPanel cannot take relative size in GWT. After searching and reading a lot, someone suggests just set the element's size to "100%" (see GWT Relative Width). I may give it a try but not sure if it will affect ScrollPanel's other function - as I will also control the scroll of the panel.

ScrollPanel myScrollPanel = new ScrollPanel();
myScrollPanel.setSize("2112px", "150px");   // Arbitrary width.
myScrollPanel.getElement().getStyle().setProperty("width", "100%");  

So here's my questions:

(1) Why??? (this is driving me mad as I cannot understand, maybe someone with deeper understanding of the GWT inside mechanism can enlighten me)

(2) How to work around?

3
Javascript and java are far from each other. - Lain
Thanks, I know they are different. This question relates to GWT, which compiles UI wrote in Java to Javascript running in browser, so I tagged both. - Bing Ren
Alright, thanks for clarifying. - Lain
@BingRen I think you should remove the javascript tag. Following your logic you should also add a bytecode tag since the server-side GWT code is compiled to bytecode... - Adam
You can set sizes of all widgets in GWT using any units you like. They all become HTML + CSS, so everything that works (or does not) with HTML + CSS will work (or not) with GWT. - Andrei Volgin

3 Answers

1
votes

ScrollPanel implements RequiresResize interface, which means that it needs to get it size from its parent, or its size has to be set explicitly. Thus, you have two options.

(1) Use a parent widget that implements ProvidesResize interface - for example, LayoutPanel. It's important, however, that ProvidesResize - RequiresResize chain remains unbroken all the way from RootPanel to your ScrollPanel.

In a typical implementation, LayoutPanel (or its variant) represents your entire page. Then you can add various children to it, e.g. "header", "main view", "left menu", etc. For each child you can set the preferred size. For example:

myLayoutPanel.setWidgetTopBottom(myScrollPanel, 32, Unit.PX, 0, Unit.PX); 

In this example your ScrollPanel will take all available space on a page starting from 32px at the top and all the way to the bottom. You can set its position in percentages or other units instead.

(2) You can accomplish the same layout with pure CSS. If you don't care about very old browsers, the best option is to use flexbox layout model. In this case you set display: flex on your parent widget, and flex-grow: 1 on your ScrollPanel - telling it to take all available space (unless there are other flex-grow siblings, in which case they will split the extra space).

0
votes

The answer to your first question is very simple. When using the relative size for an element you are referring to the size of a parent element. So when you set height: 100% it means that your element should be 100% size of its parent.

And there are some ways to get what you want:

  • use the Viewport-percentage lengths - you can set height: 100vh which means 100% of the viewport height - this is the easiest way but may be not yet supported by all browsers

  • set both the html and body elements 100% height - this will allow you to use the relative height on child elements

  • use GWT DockLayoutPanel or DockPanel and add your scroll panel to the center pane - it will take all the remaining space

0
votes

First, ScrollPanel is something not acting as other widget for reason I don't know why. Cannot set relative size (50%), and if I give it some style, it's lost somewhere and cannot be found from page.

My solution is to use a ResizeLayoutPanel. Andrei suggested using something ProvidesResize but requires the provide / require resize chain remain unbroken, which can be very tricky. I found this ResizeLayoutPanel "ProvidesResize to its one child, but does not RequiresResize", which is the perfect candidate for the root panel of my composite. Then, I just extend the ScrollPanel to resize itself in the "onResize" method whenever it's called by the parent ResizeLayoutPanel.

Still no answer to my first question: by ScrollPanel behave like this in the first place? I tried to find answer in its source code but was not successful (though I didn't spend enough time studying the source code).

public class My100PctScrollPanel extends ScrollPanel {
    @Override
    public void onResize() {
        // Window.alert("on resize"); 
        this.setWidth(this.getParent().getOffsetWidth()+"px");
        this.setHeight(this.getParent().getOffsetHeight()+"px");
        super.onResize();
    }
}

........

compositeRoot = new ResizeLayoutPanel();  

........
scrollPanel = new My100PctScrollPanel();
compositeRoot.clear();
compositeRoot.add(scrollPanel);