GridBagLayout and its pitfals

Discussion in 'Java' started by nukleus, Feb 8, 2007.

  1. nukleus

    nukleus Guest

    This is a repost of the original post with
    Subject: Nested GridBagLayout and its pitfals.

    I decided that the subject would be easier to find
    if the first word was GridBagLayout.
    Secondly, I'd like to fix some obvious errors
    in the original post and I hope that the followups,
    if any, would be on this thread.

    - - - - - - - - - - - - - - - - - - - - - -
    Original post:

    I am working on one app that has few frames
    to get/set various program parameters.

    Some of those frames have several buttons,
    several text fields with labels, several checkboxes,
    a text area and, status field and a choice boxes.

    To make it all look nice and clear from the standpoint
    of GUI element layout, you would have to get into
    some pretty hairy issues.

    Working with it, what I was seeing is nothing less
    than magic. Buttons would dissapear in run time,
    text fields would have Y size several times smaller
    than the font Y size and on and on an on.
    I could not believe my eyes seeing all that madness,
    and I ended up spending probably 10 times more time
    on it all, than it should have taken me, or any
    mortal for that matter.

    I decided to use my gadget and review the 25000
    article archive of this group, going back at least
    half a year, and see if this issue was ever discussed.
    The result was nothing but shock. There were but a
    handful of articles, most in Sept. 2006, addressing
    this issue, and even there, the advices were so
    scetchy, that they were virtually useless,
    in case of just about any realistic frame imaginable
    having more than a few similar GUI elements.

    So, let us attempt to fix that problem
    and put an end to the whole GridBagLayout debate.

    I was recomended by one of people here to read the
    Sun's tutorial on GridBagLayout. Yes, I agree, it
    is humanly readable, but, unfortunately, the example
    it provides is nothing more than a childish invention,
    and there is very little chance it is going to be of
    any use in any realistic sutuation.
    It does not address ANY of subtleties of realistic layouts,
    having not just a bunch of buttons,
    filling the entire frame, but a mix of various GUI
    elements.

    Finally, what i came up with, was a realization
    that about the easiest and the best way of doing it,
    was to use nested layouts.

    Here is summary of what I have found.
    It is all out of memory as I do not want to load
    another piece of bloatware and wait for days
    when I want to switch some tab. So, some things
    may be named incorrectly, but that is not significant
    as the very underlying meaning should be clear.

    1. In just about any realistic GUI frame,
    you are likely to have a mix of various elements.
    If you try to lay them all out using a single
    GridBagLayout, you'll waste half of your life,
    being blown out of the chair when you change
    any parameters.

    You may try to cheat and create more grid cells,
    trying to properly position various unrelated
    groups of elements, trying to make one GUI element
    to occupy more than one cell in X/Y dimension,
    trying to accomodate for your positioning requirements,
    but it will likely to und up in nothing less than
    utter frustration.

    So, use nested layout instead.

    Meaning: Organize all of your similar GUI
    elements into logically related areas on your
    frame. Group buttons in one group, labels and
    text fields in another group, and so the checkboxes,
    text areas and the rest of it.

    2. Create separate panels for each group of related GUI elements

    Use GridBagLayout for each of those panels.
    For the group of checkboxes, GridBagLayout is not
    the best choice as it does not guarantee the equal
    X offsets between the checkboxes.

    So, for check box panel, use GridLayout instead
    as it guarantees the equal X size distribution
    between all the checkboxes.

    Use GridBagLayout for the frame itself, and put
    all those panels into separate cells of the frame's
    GridBagLayout.

    3. Avoid using fills and weights as much as possible

    as their effect may be such that you'll never have
    a handle on your layout. Say, for example, you have
    a group of labels, in Y dimension, that label the
    corresponding text fields. The entire row of labels
    will be dimensioned at run time to have an X size
    of the label having the longest text string.
    (In fact, in each row, you don't have to worry
    about the size of each column. At run time,
    the largest size will be used for the entire column).

    If you use fills to pad the label column size,
    and, later on, decide to change the text of your
    longest label and make it much smaller, all of a
    sudden, your whole layout will change.

    Fills are not the absolute size of some GUI element.
    They are what needs to be added to the size of a
    text string, that element contains, be it label,
    button, text field. That is why their are called
    paddings, which should immediately turn the warning
    lights on.

    That means that if you use fills hoping to maximize
    the size of some row or a column, you'll be sweating
    half of your life to make it all work, especially if you
    try to resize that frame in run time.

    Use insets instead. Those are guaranteed not to change
    regardless of the size of your GUI element. The easiest
    thing to think of them is margins. They are expressed
    in absolute terms - pixels.

    4. Minimize the number of constraint parameters used

    Try to keep all the values of constraints structures
    at zero instead of filling them with values you THINK
    will make it look better. Use only those parameters
    that you feel are absolutely necessary, such as insets.

    The exception is the row/column numbers and a number
    of cells you want your GUI element to occupy in X or Y
    dimension.

    5. Paddings of labels, text fields and text related elements

    On all labels, use a small X padding of 3 - 6 pixels
    for the labels so that the text field, following that
    label in X position have some margin and does not run
    into the end of the label string.

    Do not use fills or weights on labels, because you will
    probably want them to stay of exactly the same size and
    remain the same margins in between when you resize the
    frame unless they label some elements that will change
    their position with resizing.

    6. Using fills and paddings

    Try not to use paddings for any of constraints structures
    for each of your GUI elements, hoping to increase the
    column width, unless it is absolutely necessary in such
    cases as when you want to guarantee the minimum length of
    a text field in X dimension.

    Paddings are only used to guarantee you extra space
    in your text fields, text areas, labels, buttons, etc.

    They should not be used in hope to adjust the column widths
    as, during the render time, the effects may be utterly
    different than those you thought you achieved during design
    time. Secondly, if you change the text of your label or your
    text field, the effect of padding may end up being something
    utterly different than what you were hoping to achive.

    For example, using paddings on your text fields in Y dimension,
    will increase the Y margin between the different label/text
    fields in a group, but when you consider weights, the run time
    behavior may be simply unpredictable.

    You would probably want your fields and labels to stay equally
    positioned regardless of the size of your frame
    and to be guaranteed their minimum size as limited by the
    font you are using and the length of your string.

    7. Testing frame during run time

    Try to make your frame resizable and resize it in
    run time. If all the GUI elements and groups keep sane
    proportions, it means you've got all your constraints
    and structure of your nested layout correctly configured.

    8. Using off the shelf GUI designer

    If you use a GUI designer, and it generates Java code
    for your constraints, panels, etc., do not modify that
    code by hand. You'll waste half of your life if you
    ever need to change your layout in the future, which
    is pretty much inevitable. All your hand coded stuff
    will be either overwritten, or might cause unpredictable
    behavior of your new version.

    The same exact code as generated by the GUI designer
    should work like a champ in just about ANY situation
    imaginable.

    Forget about the minimum and preferred sizes.
    They are virtually useless. You can put some
    reasonable values in them, but when you try to
    resize your frame, and hope they mean something,
    you may be suprised that the minimum and preferred
    sizes are simply ignored, as far as having anything
    to do with the look and feel of your frame.
    I just set them to some reasonable values and forget
    about them. Even if they are set to 0, and frame
    is correctly designed, you won't have problems
    with it in run time.

    9. Simplicity of proper structuring

    If you do your design correctly, you'll have the
    absolute minimum of various parameters to be set
    as far as boundaries, sizes, etc.,
    behaving in the most predictable way
    possible under the Sun.

    10. Separation of GUI and the even handling code

    Separate your GUI related code for the frame
    and do not add anything to that class beyond
    get/set methods for each element.

    Make a superclass that extends that frame and that
    is where you can add the keyboard and mouse listeners,
    and all the bells and whistes to your frame. That
    superclass has access to its underlying frame's
    variables and has the right to do anything it pleases
    with those variable, even though it should not attempt
    to modify the sizes, constraints etc.
    It all has to be done by the code generated by your
    GUI designer.

    11. Proprietary layout managers

    Try not to use some proprietary layout managers
    because they are not guaranteed to work with the
    future versions, unless they rely on the existing
    basic layouts, which you can do yourself.

    Futhermore, they'll end up doing the same thing
    the GridBagLayout or other basic layouts do, and,
    if you are trying to be lazy, hoping to save some
    time or effort, you are likely to regret it at the end,
    it is all just a matter of time.

    Also, think about the platform compatibility.
    Are you sure you will be able to compile your code
    under different compiler or even a different version
    of the same compiler? Will it work with different version
    of jre?

    Some claim that by using some proprietary layouts,
    they can save half the amount of code lines,
    which is about the funniest argument possible.

    Your frame look and feel is about one of the most
    important aspects of your entire application.
    Just about ALL the users will see with your app
    is those very frames. Trying to save a few hundred
    bytes or code lines is simply foolish.

    Instead, let your gui designer generate as many
    constraints in wants. It does not matter at this
    state of affairs. A few hundred bytes extra
    won't change anything even worth mentioning,
    compared to overall look and feel benefits.
    But trying to hand tweak the automatically generated
    code could cost you a bundle at the end.

    12. Spend enough time on making sure your frame
    behaves in a very predictable way regardless of
    its size. All the GUI elemenents have to look
    consistent and corresponding margins and offsets
    should not change when frame is resized, unless
    you want them to and use weights to tell the
    proportional relationships.

    If your elements keep consistent behavior while
    resizing frame, it implies that all your
    constraints and the entire logical structure
    of your frame are correct.

    13. Try not to use weights, if at all possible.
    If your frame has several groups of GUI elements,
    each having several elements, then what you think
    is space distribution may end up being utterly
    different in run time and you'll waste hours if
    not days, trying to play with those weights.

    Even if you use weights with such elements as
    buttons, you may be unpleasantly suprised at
    how it looks during the render time, especially
    when you resize your frame.

    Weights refer to relative distribution of space,
    within the group of gui elements, they call
    "display area" - ugggghhhh,
    and not the frame as such.

    They do have meaning on a main frame's
    GridBagLayout, where you can adjust the
    proportional relationships between different
    groups.

    So, if you only have one group of elements
    in your frame, weights may work fine,
    but, as in any realistically complex frame,
    where you have more than one row/column of
    your main GridBagLayout, the things may and WILL
    become simply bizzare. You'll sooner go nuts
    than get the results you expect from all that
    mess. By changing any element in a different
    group of elements, the whole frame may look
    utterly ugly.

    Even to use weights for each cell of the main
    gridbag of your frame, hoping that relationship
    between groups will remain consistent, you may
    be very unpleasantly surprised with the results
    while resizing that frame or adding/removing
    some elements.

    Weights is probably close to useless if you consider
    all the remifications of using them in relatively
    complex frames. But yes, they do work. Only the
    consequences of them are much harder to predict
    than it may look at first glance.

    Summary:

    Instead of using a single GridBagLayout on just about
    any realistically complex frame, that has several
    different types of GUI elements, group the related
    elements and put them into separate panels.

    Select the layout for each panel that suits your
    frame design concepts in the easiest and most
    natural way. Do not try to make things more complex
    than necessary hoping to make it look better,
    as about ALL you are going to get at the end
    is a royal grade pain on the neck.
    It won't work. Trust me.

    Try to use GridBagLayout for all those panels
    whenever possible as this is the most general
    purpose layout having all the power to do just
    about anyting imaginable. But it has its limitations
    and unpredictability of behavior if you expect
    some rows or columns to be of equal size
    regarless of the label, text field or button text
    string sizes.

    GridBagLayout is not a good choice for that because the
    column size relationships may change in run time when
    user tries to resize the frame, and your columns will
    end up of not equal size, and, trying to make them of
    equal size, by using paddings or weights, could end up
    being a pain on the neck and of a grand proportions.

    Use as few parameters in your constraints structure
    as possible.

    By using nested gridbags, your design will end up
    being the simpliest possible with WAY more predictable
    results, the most powerful and flexible, have the smallest
    amount of various cells possible, and with the smallest
    amount of various constraint parameters, which will
    eventually translate into the most stable, predictable
    and flexible run time behavior that assures minimal amount
    of maintenance efforts of your code and provide for ease
    of future modifications.

    If you follow these few simple advises,
    you'll be amazed at how much power and flexibility
    you can achieve with nested GridBagLayout.

    Good luck.

    Finally, if any experts around have any comments,
    it would probably be a good idea to clarify some
    more subtle points and issues, or correct some
    errors or philosophical fine points as this information
    will become a permanent reference on this issue
    and will be available through argives for generations
    to come.

    Simmply sending people to read some Sun "tutorial",
    you are effectively sending them to hell,
    as those "tutorials" cover only the most primitive
    and most basic concepts having virtually nothing
    to do with a realistic application.

    Instead, you can spend half an hour of your time
    and spill out the fine points of this most important
    thing there is in the entire concept of GUI design,
    GridLayout, which all would have to learn eventually
    no matter what.
     
    nukleus, Feb 8, 2007
    #1
    1. Advertising

  2. nukleus

    hiwa Guest

    On Feb 9, 5:09 am, (nukleus) wrote:

    > to use nested layouts

    It'a classic common sense in GUI programming in
    general, not confined to Java.

    Some of your listed comments I don't agree upon but
    that is not important for me and probably for others.
     
    hiwa, Feb 8, 2007
    #2
    1. Advertising

  3. nukleus

    nukleus Guest

    In article <>, "hiwa"
    <> wrote:
    >On Feb 9, 5:09 am, (nukleus) wrote:
    >
    >> to use nested layouts

    >It'a classic common sense in GUI programming in
    >general, not confined to Java.
    >
    >Some of your listed comments I don't agree upon but
    >that is not important for me and probably for others.


    Well, you could take time and comment on specific
    issues.
     
    nukleus, Feb 9, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. nukleus
    Replies:
    8
    Views:
    575
    nukleus
    Feb 10, 2007
  2. nukleus

    GridBagLayout and its pitfals

    nukleus, Feb 9, 2007, in forum: Java
    Replies:
    0
    Views:
    420
    nukleus
    Feb 9, 2007
  3. thunk
    Replies:
    1
    Views:
    359
    thunk
    Mar 30, 2010
  4. thunk
    Replies:
    0
    Views:
    536
    thunk
    Apr 1, 2010
  5. thunk
    Replies:
    14
    Views:
    659
    thunk
    Apr 3, 2010
Loading...

Share This Page