3

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.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
user1945612
  • 31
  • 1
  • 2
  • Nope, that doesn't work. However, you comment got me messing around with the code a bit more, and I discovered that if I set the size with "setSize(500, 500);" then "setResizable(false);" and finally "pack();" it seems to work perfectly, but I'm not sure why. It doesn't seem to work any other way. – user1945612 Jan 04 '13 at 04:33
  • For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Jan 04 '13 at 05:11
  • Thanks, will do next time – user1945612 Jan 04 '13 at 06:10
  • 1
    [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing](http://stackoverflow.com/q/7229226/230513)? – trashgod Jan 04 '13 at 09:53
  • *"will do next time"* Will look at your question, next time. – Andrew Thompson Jan 04 '13 at 17:45
  • Sorry, first question asked, I'm new to the site and I just now noticed the edit option for my question. You don't need to be rude to point out ignorance. – user1945612 Jan 05 '13 at 10:44

3 Answers3

3

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...

higuaro
  • 15,730
  • 4
  • 36
  • 43
arcy
  • 12,845
  • 12
  • 58
  • 103
2

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]
higuaro
  • 15,730
  • 4
  • 36
  • 43
  • Yes, but the panel is still 510 by 530, you just can't see it because the frame is only 500 by 500. When I try to add elements to the panel they extend off the screen. – user1945612 Jan 04 '13 at 04:39
  • I moved the `setResizable(false)` after the `frame.setVisible(true);` and it works, prints `java.awt.Dimension[width=500,height=500]` now. Test it please – higuaro Jan 04 '13 at 04:48
  • Tried it, and it works, but creates problems of it's own. The frame is now larger than the panel, at least for me. When I add `System.out.println(frame.getSize());` right before the call for the app size. It returns `java.awt.Dimension[width=516,height=536]` Very stange – user1945612 Jan 04 '13 at 06:08
0

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();
 }
user11153
  • 8,536
  • 5
  • 47
  • 50