1

Studying BoxLayout and GUI in general. I want to place a panel on a frame. Later I'll add an identical panel and will test BoxLaoyout. But I can't understand why this code produces not a panel sized 200x400 but just a red point in the middle of the left side of the frame (with coordinates about (300,0)).

public class View extends JFrame {
    public View(){
        this.setPreferredSize(new Dimension(600, 600));
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.pack();

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));

        Border border = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.BLACK);

        JPanel p1 = new JPanel();
        p1.setSize(200, 400);
        p1.setBorder(border);
        p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS));


        panel.add(p1);

        this.add(panel);
        this.setVisible(true);
    }

}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Michael
  • 4,273
  • 3
  • 40
  • 69
  • See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Jul 19 '14 at 09:48

1 Answers1

3

The layout manager (BoxLayout) is using the preferred size of the components of the container it is managing. By default, the preferred size of a empty JPanel is 0x0, adding in the border has produced a preferred size closer to 2x2

When using layout managers, calling setSize is meaningless, as the layout manager will override anything you specify when the container is revalidate

Updated

It would appear that the combination of both BoxLayouts seems to be playing against you. If I remove the second BoxLayout from p1, it seems to work okay.

Also, BoxLayout seems to want to work with the maximum size of the component...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class View extends JFrame {

    public View() {
        this.setPreferredSize(new Dimension(600, 600));
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.pack();

        JPanel panel = new JPanel();
        panel.setBorder(new LineBorder(Color.BLUE));
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));

        Border border = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.BLACK);

        JPanel p1 = new JPanel() {
            public Dimension getMaximumSize() {
                return new Dimension(200, 400);
            }
        };
        p1.setBorder(border);
        p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS));

        panel.add(p1);

        this.add(panel);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new View();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I have already experimented with the preferred size. Instead of setSize I used this line of code: p1.setPreferredSize(new Dimension(200, 400)); But the result was the same. – Michael Jul 19 '14 at 09:48