简体   繁体   中英

Java setResizable(false) changes the window size (swing)

I have a strange problem. I am using the null layout for a window (= JFrame and on windows) and if I use setResizable (false) the window size gets bigger (to right and bottom, around 10 pixels I would say). I do not know why.

The two println's return the same sizes, what is strange, also...

mainWnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWnd.setTitle(wndTitle);
mainWnd.setBounds(wndPosX, wndPosY, wndWidth, wndHeight);
System.out.println(mainWnd.getHeight() + mainWnd.getWidth());
mainWnd.setResizable(false);
System.out.println(mainWnd.getHeight() + mainWnd.getWidth());

Does somebody has an idea? Why does the window gets resized?

UPDATE: Same thing here (compile it with and without the setResizable and than you can see it, if you overlap the windows):

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Main
{
    private static JFrame mainWnd = null;

    public static void main(String[] args)
    {
        mainWnd = new JFrame();

        mainWnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainWnd.setTitle("asda");
        mainWnd.setBounds(50, 50, 300, 300);

        mainWnd.setResizable(false);

        mainWnd.setVisible(true);
    }
}

It does not change on my example, so you must have something else that causes your issue:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test4 {

    protected static void initUI() {
        JFrame frame = new JFrame("test");
        frame.setBounds(0, 0, 300, 200);
        frame.setVisible(true);
        System.err.println(frame.getSize());
        frame.setResizable(false);
        System.err.println(frame.getSize());
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                initUI();
            }
        });
    }
}

EDIT/UPDATE:

Somehow insets are incorrect when you set the resizable to false (at least on Windows 7 and JDK 6). Somehow they change from 30,8,8,8 to 25,3,3,3 although the border (which is painted by the OS) stays actually the same. Since insets are part of the bounds of the Frame, the frame is actually too big (visually) when it is not resizable. For me it looks like there is a bug in the computed insets when the frame is not resizable.

If you set setResizable false before setting the bounds, you will not have the problem. as Gergely Szilagyi stated before, you are getting rid of the scrollbars, but the size of the window is locked and therefore you end up with 9 or 10 pixels of extra space in the frame. I just had the same problem. thanks for the help.

Depending on the L&F setting the resizable(false/true) might change the window border decorations. No maximize, no resize arrow. That itself can change the size.

Replace:

frame.setResizable(false);

to:

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            frame.setResizable(false);
        }
    });

Well I have met this problem and it is a Look & Feel problem...

Why the resizable frame has an insets of (5, 5, 5, 5)? It leads me to think that make it resizable adds some extra component around the frame, like... some kind of "handler" to drag to resize ?

And then I found that if we use default Java Metal l&f and set setDefaultLookAndFeelDecorated(true) , the handler will be painted and thus, the frame will not change size. But in Nimbus, Motif and Windows L&F this point is not implemented, so it's a bug. I will report it.

My own question and my answer with GIF is here:

Swing - setResizable(true) make JFrame title bar higher and window size smaller

So far the best patch for this annoying issue is the following. Doesn't matter where you call the setResizable(false) method. Just add this piece of code after you setVisible(true) .

private void sizeBugPatch() {
    while (frame.getWidth() > yourWidth) {
        frame.pack();
    }
}

Where yourWidth is the width you've set in any of the possible ways, either manually or by overriding setPreferredSize methods. The explanation is quite easy, frame.pack() seems to reset frame.setResizable(boolean b) somehow. You could use an if instead of the while loop but I prefer while to exclude the case the window would still be extra-sized even after a second pack() .

I have a 2 JFrame subclasses defined. If I run the problem frame in a standalone app, the frame size is correct. If I run both frames in a standalone app, the problem frame is still larger. I did setResizable(false) before pack, and I still get the problem. My workaround was to change the layout to BorderLayout and plop the (image) panel in the center, then did the setResizable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM