3

My main issue is with the following piece of code when setting up a JFrame:

public Frame(){
  JPanel panel = new JPanel();
  add(panel);
  panel.setPreferredSize(new Dimension(200, 200));

  pack(); // This is the relevant code
  setResizable(false); // This is the relevant code

  setVisible(true);
}

With the following print statements we receive faulty dimensions for panel:

System.out.println("Frame: " + this.getInsets());
System.out.println("Frame: " + this.getSize());
System.out.println("Panel: " + panel.getInsets());
System.out.println("Panel: " + panel.getSize());

Output:
Frame: java.awt.Insets[top=25,left=3,bottom=3,right=3]
Frame: java.awt.Dimension[width=216,height=238]
Panel: java.awt.Insets[top=0,left=0,bottom=0,right=0]
Panel: java.awt.Dimension[width=210,height=210]

I have discovered that modifying the relevant code to the following fixes the issue:

public Frame(){
  JPanel panel = new JPanel();
  add(panel);
  panel.setPreferredSize(new Dimension(200, 200));

  setResizable(false); // Relevant code rearranged
  pack(); // Relevant code rearranged

  setVisible(true);
}

This produces the correct dimensions for our panel (using same print statements as earlier):

Frame: java.awt.Insets[top=25,left=3,bottom=3,right=3]
Frame: java.awt.Dimension[width=206,height=228]
Panel: java.awt.Insets[top=0,left=0,bottom=0,right=0]
Panel: java.awt.Dimension[width=200,height=200]

I have looked through some documentation but could not find out where these 10 pixels come from. Does anybody know why exactly this is the case?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
mez
  • 33
  • 3

1 Answers1

6

JFrame derives from Frame, and in the Frame source code for the setResizable(...) you'll see this comment:

    // On some platforms, changing the resizable state affects
    // the insets of the Frame. If we could, we'd call invalidate()
    // from the peer, but we need to guarantee that we're not holding
    // the Frame lock when we call invalidate().

Because of this, it makes sense to call pack() after calling setResizable(false).

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • So the only reason I can't call `pack()` after `setResizable(false)` is because on another platform it may change the Insets? You can see from the print statements that the Insets are the same regardless of pack() position, it's the underlying panel that has a different dimension. – mez Feb 20 '13 at 20:58
  • @mez: I've known through experimentation and through this site to call `pack()` after calling `setResizable(false)`, and the above is all I've seen by digging through the source files. But my search wasn't exhaustive, and you would probably find more by digging through more source files yourself. – Hovercraft Full Of Eels Feb 20 '13 at 21:00
  • Interesting! Thanks for the clarification. I'll see if I can dig anything up :) – mez Feb 20 '13 at 21:03