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?

4

2 回答 2

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

于 2013-08-08T22:39:38.237 回答
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 ;
}
于 2013-08-09T07:51:15.493 回答