newbie: simple layout problems

36 views
Skip to first unread message

JohnMudd

unread,
Jul 21, 2008, 11:14:04 PM7/21/08
to Google Web Toolkit
The sample program below demonstrates some layout problems I have.
My intention for this demo was just to split the screen with "Hello"
on the left and a list of msgs on the right. The msgs were supposed
to be contained withing a scrolling panel. I want to be able to
scroll this panel independent of the left side.


Here are some results before I added msgs to the logPanel. I don't
understand why the logScrollPanel width came out as zero instead of
362 like the helloPanel.

hPanel.getOffsetWidth()=725
hPanel.getOffsetHeight()=638
helloPanel.getOffsetWidth()=362
helloPanel.getOffsetHeight()=638
logScrollPanel.getOffsetWidth()=0
logScrollPanel.getOffsetHeight()=638


The height was set correctly for logScrollPanel but for some reason
the logScrollPanel does not contain the logPanel as msgs are added to
it. Here's the height after adding msgs. The scroll panel grew right
along with the logPanel instead of containing it.

logScrollPanel.getOffsetHeight()=1178


Any suggestions?




Source code:

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.*;
import java.util.*;

public class posse implements EntryPoint {

HorizontalPanel hPanel = new HorizontalPanel();
VerticalPanel helloPanel = new VerticalPanel();
VerticalPanel logPanel = new VerticalPanel();
ScrollPanel logScrollPanel = new ScrollPanel();

public void onModuleLoad() {

RootPanel root = RootPanel.get();
root.setSize("95%", "95%");

root.add(hPanel);
hPanel.setSize("100%", "100%");

hPanel.add(aPanel);
helloPanel.setSize("50%", "100%");
helloPanel.add(new Label("Hello"));
helloPanel.setBorderWidth(1);

hPanel.add(logScrollPanel);
logScrollPanel.setSize("50%", "100%");
logScrollPanel.add(logPanel);
logPanel.setBorderWidth(1);

for(int i=0; i<50; i++) {
log("test msg, i="+i);
}
}

public void log(String msg) {
logPanel.add(new Label(msg));
}
}

sloughran

unread,
Jul 22, 2008, 7:59:24 AM7/22/08
to Google Web Toolkit
Well, it doesn't look like you ever add helloPanel to hPanel. Also, I
don't see you declare aPanel, so I'm guessing that used to read
hPanel.add(helloPanel);

Setting the size like that, if you look at the tool tip you see it
needs absolute CSS units like 10px or 1em, not %'s. Try giving the
scroll panel a definite size, not a %. Example:
logScrollPanel.setSize("50%", "10em");

I think gives the effect you are looking for.

JohnMudd

unread,
Jul 22, 2008, 8:30:30 AM7/22/08
to Google Web Toolkit
Good point about using absolute units. I did get the desired scroll
effect with this: logScrollPanel.setSize("50%", "638px");
But that still leaves me confused. I checked the height after using
"100%" for height and it was 638 pixels. In my mind that should have
been good enough since, AFAIK, I didn't do anything to change the
height of the parent hPanel. The hPanel does change in height but
only because logScrollPanel doesn't stick to it's initial size. If i
can't control this simple example using relative units then what good
is GWT?

Sorry for the "aPanel" typo. My fault for editing after initial cut &
paste. Here's a clean version.

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.*;
import java.util.*;

public class posse implements EntryPoint {

HorizontalPanel hPanel = new HorizontalPanel();
VerticalPanel helloPanel = new VerticalPanel();
VerticalPanel logPanel = new VerticalPanel();
ScrollPanel logScrollPanel = new ScrollPanel();

public void onModuleLoad() {

RootPanel root = RootPanel.get();
root.setSize("95%", "95%");

root.add(hPanel);
hPanel.setSize("100%", "100%");

hPanel.add(helloPanel);
helloPanel.setSize("50%", "100%");
helloPanel.add(new Label("Hello"));
helloPanel.setBorderWidth(1);

hPanel.add(logScrollPanel);
logScrollPanel.setSize("50%", "100%");
logScrollPanel.add(logPanel);
logPanel.setBorderWidth(1);

for(int i=0; i<50; i++) {
log("test msg, i="+i);
}

log("logScrollPanel.getOffsetHeight()="+logScrollPanel.getOffsetHeight());
> > The sample program below demonstrates somelayoutproblems I have.

gregor

unread,
Jul 22, 2008, 8:47:13 AM7/22/08
to Google Web Toolkit
Hi John,

1) ScrollPanel's usually require that you set a fixed height for them
otherwise they tend to just grow to accommodate their contents. Either
you use a fixed height that always remains the same, or you can use a
WindowResizeListener and a DeferredCommand to calculate their size
relative to the client window height. This has the advantage that the
height of the ScrollPanel will be recalculated if the user changes the
their browser window size.

2) It is useful to use HorizontalPanel's setCellWidth(),
setCellHeight() etc to get the effects you want. In this example I've
set the width of helloPanel fixed at 10ems, and set the cell width for
the logScrollPanel to 100% so it takes up all remaining width in the
client area. But you can also set percentages for these cell widths.

regards
gregor


public class SandBox implements EntryPoint, WindowResizeListener {

HorizontalPanel hPanel = new HorizontalPanel();
VerticalPanel helloPanel = new VerticalPanel();
VerticalPanel logPanel = new VerticalPanel();
ScrollPanel logScrollPanel = new ScrollPanel();

public void onModuleLoad() {

helloPanel.add(new Label("Hello"));
helloPanel.setBorderWidth(1);
hPanel.add(helloPanel);
hPanel.add(logScrollPanel);
logScrollPanel.add(logPanel);
logPanel.setBorderWidth(1);

hPanel.setWidth("100%");

// fixed helloPanel width option
helloPanel.setWidth("10em");
hPanel.setCellWidth(logScrollPanel,"100%");

// percentage helloPanel width option
//hPanel.setCellWidth(helloPanel,"20%");
//hPanel.setCellWidth(logScrollPanel,"80%");

RootPanel.get().add(hPanel);
Window.addWindowResizeListener(this);
DeferredCommand.addCommand(new Command() {
public void execute() {
onWindowResized(Window.getClientWidth(),
Window.getClientHeight());
}
});

for (int i = 0; i < 50; i++) {
log("test msg, i=" + i);
}
}

public void log(String msg) {
logPanel.add(new Label(msg));
}

public void onWindowResized(int width, int height) {
// if you e.g. put a header in you would need to
// resize the ScrollPanel relative to its own top.
// if you e.g. had a footer below it you would need
// to adjust for that too
int scrollerHeight = height
- logScrollPanel.getAbsoluteTop();
if (scrollerHeight < 1) scrollerHeight = 1;
logScrollPanel.setHeight("" + scrollerHeight);

JohnMudd

unread,
Jul 22, 2008, 3:59:22 PM7/22/08
to Google Web Toolkit
Thanks, I used your suggestions to solve all but the resize problem.

I now use calls to setCellWidth() with percentage values. This
apparently is the correct way to set aside chunks of panels.

Then I call setSize() with 100% for all arguments. This apparently
just confirms that I want my widget to use the full space that has
been set aside by previous calls to setCellWidth().

I make two calls to setSize() for the scroll panel, first with 100%
values and then with absolute values. This works nicely because GWT
indirectly helps by telling me what absolute values to use.

I tried copying some of this code into a onWindowResized() type method
but I got weird results. I don't mind coding the method but I don't
want to get into the business of recalculating everything from
scratch. For now I'll give up on resizing. I'm happy if I can just
get the screen drawn as I want it one time. The users can always
refresh the app if they have to resize the window.

Here's what I ended up with. Thanks again!


import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.*;
import java.util.*;

public class posse implements EntryPoint {

HorizontalPanel hPanel = new HorizontalPanel();
VerticalPanel helloPanel = new VerticalPanel();
VerticalPanel logPanel = new VerticalPanel();
ScrollPanel logScrollPanel = new ScrollPanel(logPanel);

public void onModuleLoad() {

RootPanel root = RootPanel.get();

root.add(hPanel);
hPanel.setSize("100%", "100%");

hPanel.add(helloPanel);
hPanel.setCellWidth(helloPanel, "50%");
hPanel.setCellHeight(helloPanel, "100%");
helloPanel.setSize("100%", "100%");
helloPanel.add(new Label("Hello"));
helloPanel.setBorderWidth(1);

hPanel.add(logScrollPanel);
hPanel.setCellWidth(logScrollPanel, "50%");
hPanel.setCellHeight(logScrollPanel, "100%");
logScrollPanel.setSize("100%", "100%");
logScrollPanel.setSize(
logScrollPanel.getOffsetWidth() + "px",
logScrollPanel.getOffsetHeight() + "px"

JohnMudd

unread,
Jul 23, 2008, 4:28:30 PM7/23/08
to Google Web Toolkit
OMG, I just ran into an example where GWT gives me the wrong size for
the scroll panel via getOffsetWidth(). I have no choice but to take
the size of the parent via its getOffsetWidth(), hope that number is
correct and calculate the correct size for the scroll panel. Is it
just accepted that GWT is buggy about simple layout or am I asking for
too much?

John
> > On Jul 22, 4:14 am,JohnMudd<JohnBM...@gmail.com> wrote:
>
> > > The sample program below demonstrates somelayoutproblems I have.

Ian Bambury

unread,
Jul 23, 2008, 5:57:16 PM7/23/08
to Google-We...@googlegroups.com
Hi John,
 
Do you have a simple example of your getOffsetWidth problem?
 
How wrong is it?
 
Are we still talking about your original example?
 
Ian

Ian Bambury

unread,
Jul 23, 2008, 6:44:54 PM7/23/08
to Google-We...@googlegroups.com
Are you looking for something like this?
 
 
If that is the case, I think you might find that your problem is CSS not GWT.
 
Ian

JohnMudd

unread,
Jul 24, 2008, 3:17:54 PM7/24/08
to Google Web Toolkit
Hi, sorry I didn't see your first reply til just now. The
getOffsetWidth problem is in my full app. I don't have time to
whittle that down to an example. I just used the size of the parent
to override the value from GWT.

Your example matches my original problem. I've got that working okay
now w/o resorting to CSS. Did you use CSS?

I don't understand how GWT can give such unpredictable results and
pass it off as CSS problems.

John

Ian Bambury

unread,
Jul 25, 2008, 8:57:37 AM7/25/08
to Google-We...@googlegroups.com

Hi
Hi John,

A couple of comments:

================================

logScrollPanel.setSize("100%", "100%");
logScrollPanel.setSize(
     logScrollPanel.getOffsetWidth() + "px",
     logScrollPanel.getOffsetHeight() + "px");

I don't understand what you are trying to do here. You seem to be trying to set the scroll panel to the size of its parent and then fixing it at that size - but why?

================================

> GWT is buggy about simple layout

Without an example or any descriptions of these bugs, it is not possible to comment.
 
> I don't understand how
> GWT can give such unpredictable
> results and pass it off as CSS problems

If you set the height of a div-based widget in a table-based widget to 100% then you need to understand the effect of setting the height of a div nested inside the TD of a table to 100%.

If a programmer doesn't understand this then yes, GWT will probably seem unpredictable to them, and problems with layout *will* be fixed by changing the styling.

gregor

unread,
Jul 25, 2008, 9:02:52 AM7/25/08
to Google Web Toolkit
Hi John,

You should not have to explicitly set the width of a ScrollPanel like
that. You should set it to 100% of its container width which will be
more predictable. You do however need to set the height of a
ScrollPanel explicitly.

"I don't understand how GWT can give such unpredictable results and
pass it off as CSS problems."

The GWT compiler translates your client java code to javascript. The
javascript is run by the browser which combines it with your CSS
declarations to generate and render the final HTML display. The point
is that the browsers are in control of this rendering, not GWT,
therefore GWT (and by extension you) has to work within the
constraints of how the browsers interpret javascript and CSS
instructions.

Sometimes the different browsers don't interpret the same instructions
in exactly the same way and although the GWT team have ironed out
these differences for the standard widgets if you start writing your
own sizing code in the way you describe you may well find it doesn't
work the same across the browsers or you get unexpected results and/or
horribly complex code..

This can be confusing and very irritating initially, especially if you
are used to programming UI's in e.g. Swing or SWT, because it just
doesn't work the same way in laying out a UI display. It has its own
logic though, and CSS is an integral part of that logic, so it is a
good idea to get an early feel for how the browsers work with it
rather than fight them - they will win, not you. You should find that
once you get this most things you want to do layout-wise are a lot
simpler than might appear to you at the moment, i.e. there is almost
always a clean and relatively simple way to create either the exact
effects you want, or something very close to it.

regards
gregor

JohnMudd

unread,
Aug 3, 2008, 12:08:18 PM8/3/08
to Google Web Toolkit
Re: I don't understand what you are trying to do here. You seem to be
trying to set the scroll panel to the size of its parent and then
fixing it at that size - but why?


Whoa, I'm the one who wants to know "why?"!! :-)

Originally, in this thread, I give complete source code to an example
where the scroll panel doesn't contain the panel within it. Then
gregor replied "ScrollPanel's usually require that you set a fixed
height for them otherwise they tend to just grow to accommodate their
contents". Based on that comment I came up with a work around. That
is to (1) set the relative panel size with percents, (2) ask GWT for
the size in pixels and then (3) reset the size in absolute pixels.
NOT a pretty work around at all. First, it means my app won't re-size
if the user changes the window size. Second, and this drives me
crazy, sometimes GWT gives me the wrong size in pixels. I have a
second work around to solve that problem but I won't go into that
one. Let's focus on the original problem for now. My work around
"works" in most cases and my app is about to go into production as
is.

Please, I would love to set the size with percents alone. Is there
something wrong with my example code or is GWT just unpredictable?

Note: In my example I specify "100%". That's just an example value
for sake of simplicity. In my app I use values less that 100%.

John

Ian Bambury

unread,
Aug 3, 2008, 12:41:09 PM8/3/08
to Google-We...@googlegroups.com


2008/8/3 JohnMudd <John...@gmail.com>


Re:  I don't understand what you are trying to do here. You seem to be
trying to set the scroll panel to the size of its parent and then
fixing it at that size - but why?


Whoa, I'm the one who wants to know "why?"!!  :-)
 
Yeah, but you are trying to find out why GWT does something, and I am trying to find out why *you* are doing something.
 
I gave you an example of a project which did what you originally said you wanted (i.e. two panels, one which fills the height and will scroll) but it appears that this isn't what you really want or the thread would have died.
 
I asked for an example of getting the wrong size in pixels, but you haven't supplied it.
 
I've asked you to explain what you do actually want in more general terms - you haven't said.
 
You claim GWT is 'buggy' but you won't be specific.
 
I've asked you to explain what you are trying to do with a certain piece of code, and you tell me that *you* are the one asking questions, implying that *I* shouldn't.
 
How do you expect anyone to help you under these circumstances? You are asking people to give you their time and experience for free, remember.
 
Ian
 

JohnMudd

unread,
Aug 4, 2008, 4:46:30 PM8/4/08
to Google Web Toolkit


On Aug 3, 12:41 pm, "Ian Bambury" <ianbamb...@gmail.com> wrote:
> 2008/8/3 JohnMudd <JohnBM...@gmail.com>
>
>
>
> > Re:  I don't understand what you are trying to do here. You seem to be
> > trying to set the scroll panel to the size of its parent and then
> > fixing it at that size - but why?
>
> > Whoa, I'm the one who wants to know "why?"!!  :-)
>
> Yeah, but you are trying to find out why GWT does something, and I am trying
> to find out why *you* are doing something.
>
> I gave you an example of a project which did what you originally said you
> wanted (i.e. two panels, one which fills the height and will scroll) but it
> appears that this isn't what you really want or the thread would have died.

You gave me a link to a web site that does satisfy the original goal
of my example. I acknowledged that above, explained that with
gregor's help I already did the same without CSS (albeit I used a
goofy work around), and I asked if you used CSS to get your example
working. I'm still interested in how you got your example
working. You said my "problem is CSS not
GWT" so that makes me think you used CSS. But all I have is the link
to your working example, not source code so I'm not sure what you're
showing me.

>
> I asked for an example of getting the wrong size in pixels, but you haven't
> supplied it.

Sorry, that's a secondary problem. I don't have a simple enough
example to post here. Therefore I don't expect anyone to address that
issue. I'd rather stick to the primary issue, why is it necessary to
set the size in percents and then again in pixels? I have listed
source code for that.

>
> I've asked you to explain what you do actually want in more general terms -
> you haven't said.

The example code i listed is not far off. I just want to be able to
split a HorizontalPanel and list some messages on one half of it with
the msgs contained within a scrolling panel.

>
> You claim GWT is 'buggy' but you won't be specific.

Sorry if this discussion had led to tangents. At this point I'm still
interested in the original problem, getting the scrolling window to
use the size set with percents. I'm using a work around by resetting
the size in pixels. Not a great solution in my mind. Is there room
for improvement or is this just how GWT works?

>
> I've asked you to explain what you are trying to do with a certain piece of
> code, and you tell me that *you* are the one asking questions, implying that
> *I* shouldn't.

Sorry.


>
> How do you expect anyone to help you under these circumstances? You are
> asking people to give you their time and experience for free, remember.

Sorry. All I can do is keep trying.

>
> Ian

JohnMudd

unread,
Aug 4, 2008, 6:00:08 PM8/4/08
to Google Web Toolkit
Oh, I just now tried to resize your example and see that you have the
scrolling and resizing working. That's better than my work around.
How did you do it?

John

Ian Bambury

unread,
Aug 4, 2008, 6:46:44 PM8/4/08
to Google-We...@googlegroups.com
I'll have to work it out again :-)
 
I just did it in my GP test project
 
BTW, when I said 'CSS' I was using the term very generally, i.e. including styling  in the code which /could/ be in the css if you wanted.
 
Hang on and I'll get back to you on the example...
 
 
Ian

2008/8/4 JohnMudd <John...@gmail.com>

Stuff the environment - Print this email
_______________________________________

Ian Bambury

unread,
Aug 4, 2008, 7:11:39 PM8/4/08
to Google-We...@googlegroups.com
Here you go. I think the only thing I did which is not here is to remove the browsers normal html/body scroll bar
 
Ian
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
 
public class Main implements EntryPoint, WindowResizeListener
{
    ScrollPanel    scroller;
 
    public void onModuleLoad()
    {
        DOM.setStyleAttribute(RootPanel.getBodyElement(), "overflow", "hidden");
        // HP for the two panes
        HorizontalPanel holder = new HorizontalPanel();
        RootPanel.get().add(holder);
        holder.setWidth("100%");
 
        // VP for the left hand panel
        VerticalPanel leftVP = new VerticalPanel();
        holder.add(leftVP);
        holder.setCellWidth(leftVP, "50%");
        leftVP.add(new Label("Left Panel"));
 
        // Scrollpanel for the RH side
        scroller = new ScrollPanel();
        holder.add(scroller);
        holder.setCellWidth(scroller, "50%");
        scroller.setWidth("100%");
        setScrollerHeight();
 
        // VP within the scrollpanel
        VerticalPanel rightVP = new VerticalPanel();
        scroller.add(rightVP);
        loadRightVP(rightVP);
 
        Window.addWindowResizeListener(this);
    }
 
    void loadRightVP(VerticalPanel rightVP)
    {
        for(int i = 0; i < 100; i++)
        {
            rightVP.add(new Label("Right Panel #" + i));

        }
    }
 
    public void onWindowResized(int width, int height)
    {
        setScrollerHeight();
    }
 
    void setScrollerHeight()
    {
        scroller.setHeight(Window.getClientHeight() + "px");
    }
}

Ian Bambury

unread,
Aug 4, 2008, 7:19:29 PM8/4/08
to Google-We...@googlegroups.com
Forget the "DOM.setStyleAttribute(RootPanel.getBodyElement(), "overflow", "hidden");"
 it doesn't do anything useful.

 

JohnMudd

unread,
Aug 5, 2008, 6:25:06 AM8/5/08
to Google Web Toolkit
Okay, this confirms that I need to set the ScrollPanel height in
pixels. Thanks!

John
Reply all
Reply to author
Forward
0 new messages