0

I know I already asked this question, but due to my mistake in the example code and failure to actually ask the question, first few hours have passed and I rarely get any new comments or answers to older questions. The original was deleted.

I used this code to generate the window below (well, everything that is within the orange rectangle, to be exact):

        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        setBackground(Color.YELLOW);
        setFixedSize(new Dimension(LayoutConstants.PAGE_WIDTH + 2*LayoutConstants.HALF_SPACE_BETWEEN_PAGES, LayoutConstants.PAGE_HEIGHT + 2*LayoutConstants.HALF_SPACE_BETWEEN_PAGES));
        setBorder(BorderFactory.createLineBorder(Color.ORANGE, LayoutConstants.HALF_SPACE_BETWEEN_PAGES));

        JPanelSize header = new JPanelSize();
        header.setBackground(Color.RED);
        header.setSize(new Dimension(LayoutConstants.PAGE_WIDTH, LayoutConstants.HEADER_HEIGHT));
        add(header);

        elementContainer = new JPanelSize();
        elementContainer.setLayout(new BoxLayout(elementContainer, BoxLayout.Y_AXIS));
        elementContainer.setBackground(Color.GREEN);
        elementContainer.setFixedSize(new Dimension(LayoutConstants.CONTENT_WIDTH, LayoutConstants.CONTENT_HEIGHT));        
        add(elementContainer, BorderLayout.CENTER);


        JPanelSize footer = new JPanelSize();
        footer.setBackground(Color.MAGENTA);
        footer.setFixedSize(new Dimension(LayoutConstants.PAGE_WIDTH, LayoutConstants.FOOTER_HEIGHT));
        add(footer);

This is JPanelSize class, which simplifies my life immensely:

import java.awt.Dimension;

import javax.swing.JPanel;

public class JPanelSize extends JPanel
{
    private static final long serialVersionUID = 1L;

    public void setFixedSize(Dimension size)
    {
        setMinimumSize(size);
        setPreferredSize(size);
        setMaximumSize(size);
    }
}

And this is the result:

enter image description here

Header and footer should fill the yellow area while the green JPanel should be centered. Heights are all fine.

I'm overriding set(...)Size() methods because I'm simulating an A4 here.

What am I doing wrong?

Karlovsky120
  • 6,212
  • 8
  • 41
  • 94
  • 2
    *"What am I doing wrong?"* Using a single layout to achieve every thing. A BorderLayout would achieve the requirements for header and footer, then you could continue using a BoxLayout for the body – MadProgrammer Aug 08 '13 at 22:23
  • Make that an anwser so I can tick it. But still, I don't understand why this behaviour... I think it should have worked with my setup, no matter how bad it was... I will use your method, but I'm just confused... – Karlovsky120 Aug 08 '13 at 22:34
  • Sorry,I don't use BoxLayout, prefer GridBagLayout ;) – MadProgrammer Aug 08 '13 at 22:40

2 Answers2

3

"What am I doing wrong?" Using a single layout to achieve every thing. A BorderLayout would achieve the requirements for header and footer, then you could continue using a BoxLayout for the body

This is commonly known as compound layout and is very useful when dealing with complex layout requirements

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • See also the [Nested Layout Example](http://stackoverflow.com/a/5630271/418556) for ideas. – Andrew Thompson Aug 08 '13 at 23:02
  • using a _not-powerful enough_ layoutManager is the wrong-doing - nesting layouts has its own problems :-) @Karlovsky120 didn't you use MigLayout at one point in your never ending problem story? btw, min=max=pref sounds extremely slimy ... and is not needed with mig, it respects whatever size you configure on the manager-level. – kleopatra Aug 09 '13 at 06:46
  • @kleopatra *"nesting layouts has its own problems"* - Agreed, without further context it's difficult to provide a full proof answer. note to self, must make time to check out MigLayout :P – MadProgrammer Aug 09 '13 at 06:48
1

A technical reason (partly guessing, as you still don't show anything like a SSCCE) is a pecularity of BoxLayout: it needs its children to have the exact same alignment on the axis perpendicular to its own. That is, all children of the outer y-box must have the exact same x-alignment. If that condition isn't met, the outcome is unintuitive (the tutorial has some examples) Here the alignment mismatch is between header/footer vs. elementContainer: the former are center-aligned, the latter's alignment is calculated by its LayoutManager and is 0.

In the experiment below I can reproduce the shift of the footer, the print out of alignmentX:

header/content/footer: 0.5/0.0/0.5

A code snippet with arbitrary LayoutConstraints

JPanelSize content = new JPanelSize();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content.setBackground(Color.YELLOW);
content.setFixedSize(new Dimension(
    LayoutConstants.PAGE_WIDTH + 2*LayoutConstants.HALF_SPACE_BETWEEN_PAGES, 
    LayoutConstants.PAGE_HEIGHT + 2*LayoutConstants.HALF_SPACE_BETWEEN_PAGES));
content.setBorder(BorderFactory.createLineBorder(Color.ORANGE, 
    LayoutConstants.HALF_SPACE_BETWEEN_PAGES));

JPanelSize header = new JPanelSize();
header.setBackground(Color.RED);
header.setSize(new Dimension(LayoutConstants.PAGE_WIDTH, 
        LayoutConstants.HEADER_HEIGHT));
content.add(header);

JPanelSize elementContainer = new JPanelSize();
// comment the following line to make the container centered
elementContainer.setLayout(new BoxLayout(elementContainer, BoxLayout.Y_AXIS));
elementContainer.setBackground(Color.GREEN);
elementContainer.setFixedSize(new Dimension(LayoutConstants.CONTENT_WIDTH, 
        LayoutConstants.CONTENT_HEIGHT));        
content.add(elementContainer);

JPanelSize footer = new JPanelSize();
footer.setBackground(Color.MAGENTA);
footer.setFixedSize(new Dimension(LayoutConstants.PAGE_WIDTH, 
        LayoutConstants.FOOTER_HEIGHT));
content.add(footer);

LOG.info("header/content/footer: " 
        + header.getAlignmentX()
        + "/" + elementContainer.getAlignmentX()
        + "/" + footer.getAlignmentX()
        );
frame.setContentPane(content);

// some sizes 
public static class LayoutConstants {
    public static int CONTENT_WIDTH = 300;
    public static int CONTENT_HEIGHT = 700;
    public static int FOOTER_HEIGHT = 30;
    public static int HEADER_HEIGHT = FOOTER_HEIGHT;
    public static int HALF_SPACE_BETWEEN_PAGES = 10;
    public static int PAGE_WIDTH = 400;
    public static int PAGE_HEIGHT = CONTENT_HEIGHT 
            + FOOTER_HEIGHT + HEADER_HEIGHT ;
}
kleopatra
  • 51,061
  • 28
  • 99
  • 211