Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JFrame: get size without borders?

In Java, is it possible to get the Width and Height of the JFrame without the title and other borders?

frame.getWidth() and frame.getHeight()1 seems to return the width including the border.

Thanks.

like image 261
Tom Avatar asked Feb 23 '11 21:02

Tom


4 Answers


frame.getContentPane().getSize();

like image 156
user489041 Avatar answered Oct 01 '22 23:10

user489041


frame.pack();
System.out.println("frame width : "+getWidth());
System.out.println("frame height: "+getHeight());
System.out.println("content pane width : "+getContentPane().getWidth());
System.out.println("content pane height: "+getContentPane().getHeight());
System.out.println("width  of left + right  borders: "+(getWidth()-getContentPane ().getWidth()));
System.out.println("height of top  + bottom borders: "+(getHeight()-getContentPane().getHeight()));
like image 24
dwarfer88 Avatar answered Oct 01 '22 23:10

dwarfer88


This works fine

frame.getContentPane().getSize();

But not if you haven't added content yet. In my case, I wanted to calculate the inner dimensions of the JFrame before adding content, so I could divide up the content accordingly. Here's what I came up with.

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

pack(); // Need this, otherwise insets() show as 0.  
int scrW = (int)screenSize.getWidth();
int scrH = (int)screenSize.getHeight();
  int innerW = scrW - getInsets().left - getInsets().right;
  int innerH = scrH - getInsets().top - getInsets().bottom;

  // Need to setSize(), otherwise pack() will collapse the empty JFrame
  setSize(scrW, scrH);
like image 5
Gary Avatar answered Oct 01 '22 23:10

Gary


Here is a code snippet which works on JFrame as well as AWT's Frame (which happens to be the super-type of JFrame):

public static Dimension getInnerSize(Frame frame) {
    Dimension size = frame.getSize();
    Insets insets = frame.getInsets();
    if (insets != null) {
        size.height -= insets.top + insets.bottom;
        size.width -= insets.left + insets.right;
    }
    return size;
}

Beware: The insets are only valid once the frame has been shown.

Here is another code snippet to work around this problem:

private static Insets defaultInsets;
public static Insets getInsetsWithDefault(Frame frame) {
    // insets only correct after pack() and setVisible(true) has been
    // called, so we use some fallback strategies
    Insets insets = frame.getInsets();
    if (insets.top == 0) {
        insets = defaultInsets;
        if (insets == null) {
            insets = new Insets(26, 3, 3, 3);
            // usual values for windows as our last resort
            // but only as long as we never saw any real insets
        }
    } else if (defaultInsets == null) {
        defaultInsets = (Insets) insets.clone();
    }
    return insets;
}

This code needs to be called once with a visible Frame. After that it can correctly predict the insets even for invisible frames (due to caching of the defaultInsets), assuming they are always the same.

Of course this only works if all windows get the same window-decorations. But i am not aware of any case where they might differ from window to window.

This might be useful, too:

frame.addWindowListener(new WindowAdapter() {

    @Override
    public void windowOpened(WindowEvent e) {
        MyUtilClass.getInsetsWithDefault(frame); // init the defaultInsets
    }

});

It will call the getInsetsWithDefault() method once the window is visible and initialize the correct defaultInsets.

like image 3
Frederic Leitenberger Avatar answered Oct 01 '22 22:10

Frederic Leitenberger