2

This is a sample of the code that I am using to instantiate a JFrame:

public class TestFrame{
public static void main(String[] args){
    JFrame frame = new JFrame();
    Insets insets = frame.getInsets();
    frame.setSize(new Dimension(insets.right + insets.left + 400, insets.bottom + insets.top + 400));
    System.out.println(String.format("Top = %d \nBottom = %d \nLeft = %d \n Right
            = %d", insets.top, insets.bottom, insets.left, insets.right));

    frame.setResizable(false);
    frame.setVisible(true);
}
}

The frame is displaying fine but all of the insets seem to be equal to zero. I need to know the size of the title bar on top because I want a Content Pane of size 400x400 exactly.

I tested it on multiple platforms and the same thing happens on windows and on mac.

What am I doing wrong ?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
lilroo
  • 2,928
  • 7
  • 25
  • 34

5 Answers5

5
  1. If you want your content pane to be precisely 400x400, then I would consider setting its preferredSize to 400x400 (although I don't like to force preferred size, on a content pane, it may be acceptable, in some cases).
  2. After setting that preferred size and before showing the frame, call pack() on the frame.

This is the cleanest and easiest solution, and you don't have to care about border insets.

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • Consider overriding [`getPreferredSize()`](http://stackoverflow.com/q/7229226/230513); previously upvoted. – trashgod Oct 05 '12 at 22:30
  • @trashgod Out of curiosity, why is it better to override than setting the preferred size? – Guillaume Polet Oct 06 '12 at 15:52
  • @trashgod I already read that answer but my question was more "Why is overriding better than setting?" In the end it is all the same. As I understand the suggestion of the cited link, we should avoid setting a preferred size on nested components, but on root, it is less a problem – Guillaume Polet Oct 06 '12 at 17:41
  • @Guillaume: You are correct; I am probably jaded by too many applications that do [this](http://stackoverflow.com/a/12532237/230513). – trashgod Oct 06 '12 at 17:45
5

If contentPane should be exactly 400 x 400, then create a class that retuns this for its preferredSize and use it as the contentPane:

class MyContentPane extends JPanel {
   public static final int PREF_W = 400;
   public static final int PREF_H = 400;

   public Dimension getPreferredSize() {
     return new Dimension(PREF_W, PREF_H);
   }
}

or perhaps better:

class MyContentPane extends JPanel {
   public int prefW;
   public int prefH;

public MyContentPane(int prefW, int prefH) {
   this.prefW = prefW;
   this.prefH = prefH;
}

   public Dimension getPreferredSize() {
     return new Dimension(prefW, prefH);
   }
}

As mentioned by the other posters, you'll have to use pack() on the top level window and use layout managers.

Myself I prefer not to do this but to rather let the actual preferred sizes of various compoennts and the container's layout managers do all of this deciding for me.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • +1, we came to the same conclusion. Although simply setting the preferred size works too and does not require to extend JPanel. – Guillaume Polet Oct 03 '12 at 15:37
  • @Guillaume: I agree, but I hate being slapped by kleopatra/Jeanette for setting the preferredSize, and so I try to do it via a method override. – Hovercraft Full Of Eels Oct 03 '12 at 15:43
  • I hate that too ;-) But in this case, it seems a pretty valid approach to the problem. In the end, the result is the same and that's all that matters :-) – Guillaume Polet Oct 03 '12 at 15:45
  • 1
    @guillaume: my own preferred approach, and I'll bet yours too, is to try to avoid this whole business and to let the components tell the layout managers their preferred sizes and then let the layout managers decide the best size for the application. – Hovercraft Full Of Eels Oct 03 '12 at 15:50
  • Absolutely. This is particularly true when using nested LayoutManagers. – Guillaume Polet Oct 03 '12 at 15:52
  • +1 for overriding [`getPreferredSize()`](http://stackoverflow.com/q/7229226/230513) – trashgod Oct 05 '12 at 22:31
2
  1. Make your ui in a panel.
  2. Set the preferred size of the panel.
  3. Add the panel to frame and call pack()
Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91
  • That won't work. Try to run this and check what happens: `JFrame frame = new JFrame(); JLabel label = new JLabel("Some label"); frame.getContentPane().add(label); frame.getContentPane().setSize(400, 400); frame.pack(); frame.setVisible(true);` – Guillaume Polet Oct 03 '12 at 15:42
  • What I'm saying is not on the content pane but add another panel directly to the frame on which we set the size – Sri Harsha Chilakapati Oct 03 '12 at 15:47
  • Adding a panel on the frame is exactly the same as adding to the content pane. And even if you add an intermediary panel, it still won't work. – Guillaume Polet Oct 03 '12 at 15:54
  • See this. www.java.net/node/650887 – Sri Harsha Chilakapati Oct 03 '12 at 16:08
  • 1
    This is not what you are detailing here. In that forum, the guy is setting the size of the JFrame directly. You said to "Set the size of the panel". These are different things. And anyway, calling pack() results in setting the content pane to the size returned by getPreferredSize(). In your case, you did not set any, so this will rely on the LayoutManagers which will return a value according to what is inside the panel. Take a look at the other answers and try what you explain: you will see that it does not work. – Guillaume Polet Oct 03 '12 at 16:15
  • Thanks. Fixed it. I was on my mobile. – Sri Harsha Chilakapati Oct 03 '12 at 16:20
2

You are misunderstanding what you are working with, so it will seem "wrong".

Insets are not the dimensions of the "stuff" outside of the content pane. They are similar to a "border" around the content pane, where drawing will not be allowed to occur. Unlike borders, insets do not overlap.

The size of the decoration around the window is not determined by the program. It is determined by a different program, that handles focus, and window navigation. That program is called the window manager. It is the window manager that handles the "title bar on top" and it's height, font, etc.

To get an "exact size" program, you need to ask the window manager for a frame-less window, which can be done in Java. It will not have a title bar on top, nor will it have resizing handles near the edges, the window command menu, the red "x" to close, or a means for moving the window across your desktop (although your program can reposition itself if written to do so).

An alternative is to request an exclusive "screen" in the proper dimensions and root pane window, which was sometimes done with games. It is a more restrictive way of doing things, and resolutions are limited to supported screen sizes.

In the event that you really wanted the content pane to be a particular size, and not the whole window to be a particular size, please look to the other excellent answers that deal with a content pane's preferred size.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
0
  • BorderLayout (pre_implemented in the JFrame API) to ignore Insets,

  • most of LayoutManager ignore Insets too, only required for AbsoluteLayout,

basic and common stuff

  • JFrame (and most of Containers) can returns Insets, Bounds, Size only

    a) from already visible container

    b) after call JFrame(e.i.)#pack()

  • then in most cases is setting for Insets, Bounds, Size, XxxSize more than contraproductive, because

    a) most of JComponents can returns own and proper PreferredSize to its parent,

  • but excluding

    a) Graphics(2D),

    b) for empty containers

    c) JScrollPane & JList / JTable, there is contraproductive to generating own code monstrum in the case that JScrollPane is resizable with its container

mKorbel
  • 109,525
  • 20
  • 134
  • 319