简体   繁体   中英

Difference between Java 8 and Java 12, JFrame#setExtendedState does not work with JFrame#setPreferredSize

I want to create a JFrame that's initially maximized, and has a defined size it shrinks to when the user presses the maximize button.

Minimal example:

package minimalfullscreenexample;

import java.awt.Dimension;
import static java.awt.Frame.MAXIMIZED_BOTH;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class MinimalFullscreenExample {

    public void displayFrame() {
        JFrame frame = new JFrame("Minimal example");
        frame.setExtendedState(MAXIMIZED_BOTH);
        frame.setPreferredSize(new Dimension(500, 300));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(()  -> { new MinimalFullscreenExample().displayFrame(); });
    }
}

Expected behaviour: The window openes maximized. When the user clicks the maximize button, the window becomes un-maximized, and has a size of 500x300 pixels.

This works as it should with

  • Linux, oracle jdk 1.8.0_201
  • Linux, openjdk 1.8.0_252
  • Linux, openjdk 11.0.7
  • Linux, openjdk 12.0.1
  • Windows, oracle jdk 1.8.0.171 (old version, I know, but.. the example works)

This does NOT work with

  • Windows, openjdk 12.0.1

where the window opens un-maximized.

When the setPreferredSize call is removed, the window opens maximized, but shrinks to "nothing" on un-maximizing.

Is there any know bug or workaround for that? (Moving the setPreferredSize above setExtendedState doesn't help).

I've had the same problem, but i managed to solve it.
The problem is frame.pack().
In fact, it sets the size of the frame to its preferred size. I've also noticed the difference between Java 8 (or 9) and Java 12, I think it's a bug on the openjdk.

However, to fix this, you should call setExtendedState after calling pack(), like this:

package minimalfullscreenexample;

import static java.awt.Frame.MAXIMIZED_BOTH;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class MinimalFullscreenExample {

    public void displayFrame() {
        JFrame frame = new JFrame("Minimal example");
        frame.setPreferredSize(new Dimension(500, 300));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setExtendedState(MAXIMIZED_BOTH); // after frame.pack()
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new MinimalFullscreenExample().displayFrame();
        });
    }
}

I think you are simply misunderstanding the effect of pack :

Causes this Window to be sized to fit the preferred size and layouts of its subcomponents . The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.

Your use case is probably the explanation:

  • You are putting the window to maximized state, so its size should be the size of the screen minus desktop border. This is however specific to the platform (Windows, Linux and the other OS I don't want to recognize:)).
  • You have no component beside the content pane and put a preferred size on the window rather than its content pane. JFrame may delegate to content pane, but the LayoutManager may simply ignore the preferredSize (for example, BorderLayout ignore it for the CENTER constraint), same apply for minimum (which is 0, 0 here) and maximum size (which is (Integer.MAX_VALUE, Integer.MAX_VALUE) or (Short.MAX_VALUE, Short.MAX_VALUE) ).
  • You call pack, which affect the size for the unmaximized state: the size is probably invalid.

What may have changed between Java 11 and 12 is the native call to resize the window: it may simply disallow you from changing the size to (0,0) or negative values which may be considered an error for the Window Manager . Java may introduce another layer (eg: validate size) or not.

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