BoxLayout Woes

Discussion in 'Java' started by Aaron Fude, Nov 7, 2008.

  1. Aaron Fude

    Aaron Fude Guest

    Hi,

    I have always had trouble layout out components by using BoxLayouts
    because I have always found them unpredictable, if not outright buggy.
    (I'm actually surprised there aren't more threads on this issue so
    perhaps my understanding of this is flawed.) I have historically been
    able to solve those problems by a combination of fillers, rigid boxes,
    max size, min sizes, preferred size, out sizes, etc;

    But now I have a problem that I am unable to solve;

    I add a panel A and then a panel B to a panel C, whose layout manager
    is BoxLayout(X_AXIS);
    I check the min size, the pref size and the max size on A. Looking at
    widths only, the preferred width is 524 and the maximum width is 462.
    (By the way, that right there doesn't make sense to me.)

    Then, if I only add panel A to C, its size ends up being 462. But if I
    add A and B to C, then its width ends up being 524 which results in a
    lot of empty space. What gives? And how to I control this behavior? I
    don't set sizes anywhere in the code.

    Many thanks in advance,

    Aaron
     
    Aaron Fude, Nov 7, 2008
    #1
    1. Advertising

  2. Aaron Fude

    Eric Sosman Guest

    Aaron Fude wrote:
    > Hi,
    >
    > I have always had trouble layout out components by using BoxLayouts
    > because I have always found them unpredictable, if not outright buggy.
    > [...]
    > Then, if I only add panel A to C, its size ends up being 462. But if I
    > add A and B to C, then its width ends up being 524 which results in a
    > lot of empty space. What gives? And how to I control this behavior? I
    > don't set sizes anywhere in the code.


    May we see a short (but complete and compilable) example of
    your code?

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 7, 2008
    #2
    1. Advertising

  3. Aaron Fude

    Lew Guest

    On Nov 6, 11:15 pm, Eric Sosman <> wrote:
    > Aaron Fude wrote:
    > > Hi,

    >
    > > I have always had trouble layout out components by using BoxLayouts
    > > because I have always found them unpredictable, if not outright buggy.
    > > [...]
    > > Then, if I only add panel A to C, its size ends up being 462. But if I
    > > add A and B to C, then its width ends up being 524 which results in a
    > > lot of empty space. What gives? And how to I control this behavior? I
    > > don't set sizes anywhere in the code.

    >
    >      May we see a short (but complete and compilable) example of
    > your code?


    To assist with that, see
    <http://sscce.org/>

    Thanks, Andrew Thompson.

    --
    Lew
     
    Lew, Nov 7, 2008
    #3
  4. Aaron Fude

    Aaron Fude Guest

    On Nov 7, 3:37 pm, RedGrittyBrick <>
    wrote:
    > Aaron Fude wrote:
    > > Hi,

    >
    > > I have always had trouble layout out components by using BoxLayouts
    > > because I have always found them unpredictable, if not outright buggy.
    > > (I'm actually surprised there aren't more threads on this issue so
    > > perhaps my understanding of this is flawed.) I have historically been
    > > able to solve those problems by a combination of fillers, rigid boxes,
    > > max size, min sizes, preferred size, out sizes, etc;

    >
    > > But now I have a problem that I am unable to solve;

    >
    > > I add a panel A and then a panel B to a panel C, whose layout manager
    > > is BoxLayout(X_AXIS);
    > > I check the min size, the pref size and the max size on A. Looking at
    > > widths only, the preferred width is 524 and the maximum width is 462.
    > > (By the way, that right there doesn't make sense to me.)

    >
    > That doesn't make sense to me either. It depends on the components
    > you've added to A. Perhaps you've dome something weird?
    >
    >
    >
    > > Then, if I only add panel A to C, its size ends up being 462. But if I
    > > add A and B to C, then its width ends up being 524 which results in a
    > > lot of empty space. What gives?

    >
    > What gives is probably in error in the code you are not showing us.
    >
    > > And how to I control this behavior? I
    > > don't set sizes anywhere in the code.

    >
    > Good. Nor should you IMHO.
    >
    > I get consistent sizing of A at it's preferred size regardless of
    > whether or not I add B to C
    >
    > ---------------------------------------8<--------------------------------
    > import java.awt.Color;
    > import java.awt.Dimension;
    > import java.awt.event.ActionEvent;
    > import java.awt.event.ActionListener;
    >
    > import javax.swing.BoxLayout;
    > import javax.swing.JFrame;
    > import javax.swing.JLabel;
    > import javax.swing.JPanel;
    > import javax.swing.SwingUtilities;
    > import javax.swing.Timer;
    > import javax.swing.border.LineBorder;
    >
    > /**
    >   * @author RedGrittyBrick
    >   */
    > public class BoxTest implements ActionListener {
    >
    >      private JLabel labelA = new JLabel("this is panel A");
    >      private JPanel panelA;
    >
    >      public static void main(String[] args) {
    >
    >          final BoxTest boxTest = new BoxTest();
    >          Timer timer = new Timer(500, boxTest);
    >          timer.setInitialDelay(1000);
    >          timer.start();
    >
    >          SwingUtilities.invokeLater(new Runnable() {
    >              @Override
    >              public void run() {
    >                  boxTest.createAndShowGUI();
    >              }
    >          });
    >      }
    >
    >      void createAndShowGUI() {
    >          labelA.setMinimumSize(new Dimension(300, 188));   // To
    >          labelA.setPreferredSize(new Dimension(512, 188)); // force
    >          labelA.setMaximumSize(new Dimension(462, 188));   // oddity
    >          panelA = new JPanel();
    >          panelA.setBorder(new LineBorder(Color.BLUE));
    >          panelA.add(labelA);
    >
    >          JPanel panelB = new JPanel();
    >          panelB.setBorder(new LineBorder(Color.RED));
    >          panelB.add(new JLabel("PanelB"));
    >
    >          JPanel panelC = new JPanel();
    >          panelC.setLayout(new BoxLayout(panelC, BoxLayout.LINE_AXIS));
    >          panelC.add(panelA);
    >          //panelC.add(panelB);
    >
    >          JFrame f = new JFrame("BoxTest");
    >          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    >          f.add(panelC);
    >          f.pack();
    >          f.setLocationRelativeTo(null);
    >          f.setVisible(true);
    >      }
    >
    >      @Override
    >      public void actionPerformed(ActionEvent arg0) {
    >          Dimension size = panelA.getSize();
    >          labelA.setText(size.width + " x " + size.height);
    >      }}
    >
    > ---------------------------------------8<--------------------------------
    >
    > Show us an SSCCE that reproduces the behaviour you describe.
    >
    > --
    > RGB- Hide quoted text -
    >
    > - Show quoted text -



    Hi again,

    I put together a little demo that shows some of the strange behavior,
    although not exactly what I described in the previous post. You see
    that I expand the frame, the the (red) JPanel grows to a point and the
    decides to go back to it's "packed" size. What is it that I do that
    could cause that? I would not be able to post a SSCCE example,
    everything is too intertwined.

    Here's the Demo:

    http://freeboundaries.com/JPanel.html

    Thanks again,

    Aaron
     
    Aaron Fude, Nov 8, 2008
    #4
  5. Aaron Fude wrote:
    > RedGrittyBrick wrote:
    >> Aaron Fude wrote:
    >>> Hi,
    >>> I have always had trouble layout out components by using BoxLayouts
    >>> because I have always found them unpredictable, if not outright buggy.
    >>> (I'm actually surprised there aren't more threads on this issue so
    >>> perhaps my understanding of this is flawed.) I have historically been
    >>> able to solve those problems by a combination of fillers, rigid boxes,
    >>> max size, min sizes, preferred size, out sizes, etc;
    >>> But now I have a problem that I am unable to solve;
    >>> I add a panel A and then a panel B to a panel C, whose layout manager
    >>> is BoxLayout(X_AXIS);
    >>> I check the min size, the pref size and the max size on A. Looking at
    >>> widths only, the preferred width is 524 and the maximum width is 462.
    >>> (By the way, that right there doesn't make sense to me.)
    >>> Then, if I only add panel A to C, its size ends up being 462. But if I
    >>> add A and B to C, then its width ends up being 524 which results in a
    >>> lot of empty space. What gives?
    >>> And how to I control this behavior?

    >>
    >> I get consistent sizing of A at it's preferred size regardless of
    >> whether or not I add B to C
    >>


    [my SSCCE counter-example omitted]

    >>
    >> Show us an SSCCE that reproduces the behaviour you describe.
    >>

    >
    > Hi again,
    >
    > I put together a little demo that shows some of the strange behavior,
    > although not exactly what I described in the previous post. You see
    > that I expand the frame, the the (red) JPanel grows to a point and the
    > decides to go back to it's "packed" size. What is it that I do that
    > could cause that?


    I've no idea, BoxLayout has always worked in a predicable way for me.
    I've seen GridBagLayout do similar things (google for totallygridbag).

    > I would not be able to post a SSCCE example,
    > everything is too intertwined.


    Well either untangle it (which would be sound software engineering and a
    good thing to do anyway) or create an SSCCE from scratch.

    I suspect the intertwining is at the root of your problem. Remove it!


    >
    > Here's the Demo:
    >
    > http://freeboundaries.com/JPanel.html
    >


    Well good, whilst that video demonstrates a strange visual effect, I
    find it to be of no use in discovering exactly what in your source code
    is causing that effect.

    You seem to imagine that BoxLayout contains a well known bug that causes
    that effect and that everyone else will say "aha that's the xxx bug,
    here's a workaround." That is not the case.

    An SSCCE is the best way forward. I suggest you make a copy of the
    project and delete ruthlessly until you have less than 120 lines of code
    that demonstrate the problem.



    The following SSCCE reproduces your layout pretty exactly but does
    not show the undesired effect shown in your video.
    --------------------------------8<-----------------------------------
    import java.awt.Color;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;

    import javax.swing.BorderFactory;
    import javax.swing.Box;
    import javax.swing.BoxLayout;
    import javax.swing.JCheckBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    import javax.swing.border.CompoundBorder;
    import javax.swing.border.EmptyBorder;
    import javax.swing.border.LineBorder;

    /**
    * @author RedGrittyBrick
    */
    public class BoxLayoutTest {

    public static void main(String[] args) {
    final BoxLayoutTest boxTest = new BoxLayoutTest();
    SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
    boxTest.createAndShowGUI();
    }
    });
    }

    void createAndShowGUI() {
    JPanel panel = new JPanel();
    panel.setBorder(BorderFactory.createTitledBorder("Addresses"));
    panel.setBackground(Color.RED);
    panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
    panel.add(new PairPanel());
    panel.add(new PairPanel());

    JFrame f = new JFrame("BoxTest");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(panel);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
    }

    class PairPanel extends JPanel {
    PairPanel() {
    setBackground(PALE);
    setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    add(new AddressPanel());
    add(Box.createHorizontalStrut(8));
    add(new AddressPanel());
    add(Box.createHorizontalGlue());
    }
    }

    class AddressPanel extends JPanel {
    AddressPanel() {
    setBorder(new CompoundBorder(new EmptyBorder(3, 3, 3, 3), //
    new LineBorder(Color.GRAY)));
    setBackground(PALE);
    setLayout(new GridBagLayout());
    GridBagConstraints gc = new GridBagConstraints();
    gc.insets = new Insets(1, 3, 0, 3);
    gc.fill = GridBagConstraints.HORIZONTAL;

    gc.anchor = GridBagConstraints.LINE_START;
    gc.gridwidth = 1;
    JTextField category = new JTextField(8);
    category.setMinimumSize(category.getPreferredSize());
    category.setBackground(Color.BLUE);
    add(category, gc);
    gc.gridwidth = GridBagConstraints.REMAINDER;
    add(new JCheckBox("Primary"), gc);

    add(new JTextField(16), gc);

    add(new JTextField(16), gc);

    gc.insets = new Insets(1, 3, 3, 0);
    gc.gridwidth = 2;
    add(new JTextField(10), gc);
    gc.insets = new Insets(1, 0, 3, 0);
    gc.gridwidth = 1;
    add(new JLabel(", "), gc);
    add(new JTextField(2), gc);
    add(Box.createHorizontalStrut(10), gc);
    gc.insets = new Insets(1, 3, 3, 3);
    gc.gridwidth = GridBagConstraints.REMAINDER;
    add(new JTextField(4), gc);

    setMaximumSize(getPreferredSize()); // prevent growth
    setMinimumSize(getPreferredSize()); // prevent shrink
    }
    }

    static final Color PALE = new Color(232, 232, 232);

    }
    --------------------------------8<-----------------------------------
    Note: I had to work hard to make stretching the frame add dead-space to
    the right (as in your video) rather than adding to the length of
    JTextFields or otherwise producing a more pleasing visual behaviour.
    Nevertheless, it does exactly what you seem to want it to do, without "bug".

    --
    RGB
     
    RedGrittyBrick, Nov 9, 2008
    #5
  6. RedGrittyBrick wrote:

    P.S. in my SSCCE change
    panel.add(new PairPanel());
    panel.add(new PairPanel());
    to
    panel.add(new PairPanel());
    panel.add(Box.createVerticalStrut(5));
    panel.add(new PairPanel());


    --
    RGB
     
    RedGrittyBrick, Nov 9, 2008
    #6
  7. RedGrittyBrick wrote:
    > I've no idea, BoxLayout has always worked in a predicable way for me.
    > I've seen GridBagLayout do similar things (google for totallygridbag).


    I've written my own helper class just to wrap the use of GridBagLayout
    and GridBagConstraints, it can be so noisome to use.
     
    public boolean, Nov 11, 2008
    #7
  8. public boolean wrote:
    > RedGrittyBrick wrote:
    >> I've no idea, BoxLayout has always worked in a predicable way for me.
    >> I've seen GridBagLayout do similar things (google for totallygridbag).

    >
    > I've written my own helper class just to wrap the use of GridBagLayout
    > and GridBagConstraints, it can be so noisome to use.


    Now I've got my own BoxLayout woes. I'll be posting a new thread though.
     
    public boolean, Nov 12, 2008
    #8
    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. Ryan Stewart

    BoxLayout bug in 1.5?

    Ryan Stewart, Feb 23, 2005, in forum: Java
    Replies:
    10
    Views:
    4,530
    Ryan Stewart
    Mar 2, 2005
  2. Sean Anderson

    Box, Boxlayout problem

    Sean Anderson, May 14, 2005, in forum: Java
    Replies:
    3
    Views:
    487
    Sean Anderson
    May 15, 2005
  3. alex_us01
    Replies:
    9
    Views:
    14,610
    Roedy Green
    Oct 1, 2005
  4. Christian Otteneuer

    Alignment in Swing-BoxLayout

    Christian Otteneuer, Jul 8, 2006, in forum: Java
    Replies:
    0
    Views:
    601
    Christian Otteneuer
    Jul 8, 2006
  5. public boolean

    My own BoxLayout woes

    public boolean, Nov 12, 2008, in forum: Java
    Replies:
    5
    Views:
    458
    public boolean
    Nov 17, 2008
Loading...

Share This Page