user1945612
user1945612

Reputation: 31

What's overriding my preferred size? (JPanel)

So I'm pretty new to GUI, and came across the problem that whatever I set my preferred size to ( via setPreferredSize(new Dimension(width, height)) ) it adds 10 to both width and height. I was wondering, why does this happen? Yes I understand that it is "preferred size" but surely there is a way to prevent this. I can fix it by simply subtracting 10 from width and height before passing it to the method, but I was wondering what was going on.

My (relevant) Code:

Main method:

 public static void main(String[] args)
 {
    final App app = new App(500, 500);

    JFrame frame = new JFrame("Block Stacker 3000");
    frame.getContentPane().add(app);
    frame.pack();
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    System.out.println(app.getSize());
    app.start();
 }

App constructor (extends JPanel):

  public App(int width, int height)
  { 
     this.width = width;
     this.height = height;

     System.out.println(width + " " + height);

     setPreferredSize(new Dimension(width , height));

     setBackground(Color.CYAN);
  }

When run, it outputs the following:

500 500
java.awt.Dimension[width=510,height=510]

Also, I've tried using setMinimumSize() and setMaximumSize() but neither really affected anything.

Upvotes: 3

Views: 4763

Answers (3)

user11153
user11153

Reputation: 8876

You must call pack() after calling setResizable(false), because when window is resizeable, layout manager will leave 10px margin for (potential) scrollbars.

public static void main(String[] args) {
    final App app = new App(500, 500);

    JFrame frame = new JFrame("Block Stacker 3000");
    frame.getContentPane().add(app);
    frame.setResizable(false);
    frame.pack();

    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    System.out.println(app.getSize());
    app.start();
 }

Upvotes: 0

dinox0r
dinox0r

Reputation: 16039

I copied/pasted your code and got the following output:

500 500
java.awt.Dimension[width=510,height=530]

But then, I toke a screenshot of the frame:

enter image description here

If you download the picture and check the file properties, you will see that it is 502 pixels width (due to the window 1 pixel thin border) and 531 pixels height (due to the window title bar 31 pixels height), checking the image in gimp, I could find that the Cyan area is in fact 500x500 pixels wide.

UPDATE: Move the setResizable(false) sentence to the line after frame.setVisible(true);:

    JFrame frame = new JFrame("Block Stacker 3000");
    frame.getContentPane().add(app);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    frame.setResizable(false);

After that, it will print:

500 500
java.awt.Dimension[width=500,height=500]

Upvotes: 2

arcy
arcy

Reputation: 13103

The size of your JPanel is going to be determined by the layout manager handling the components in its container. JFrame has a default layout manager, so there is one even though you are not setting it. Some layout managers pay attention to preferred size, some don't, some pay more attention to minimum/maximum size than others.

You can set a "null layout manager", also known as "absolute positioning", and control all the sizes yourself, but I would think you aren't trying to do that (since you are setting a "preferred" size). What you will need to do to design your UI is figure out what relative sizes and positions you want things to have AND what you want to happen to them when the size of the window changes; that determines which layout managers go onto and into which container panels and the container panels that contain them, etc.

And I wouldn't eliminate frame.pack(); it essentially tells the layout manager to do its stuff, and you usually WANT the layout manager to handle things once you get them set up the way you want them...

Upvotes: 3

Related Questions