【问题标题】:Difference between Java 8 and Java 12, JFrame#setExtendedState does not work with JFrame#setPreferredSizeJava 8 和 Java 12 之间的区别,JFrame#setExtendedState 不适用于 JFrame#setPreferredSize
【发布时间】:2023-03-04 01:09:02
【问题描述】:

我想创建一个最初最大化的 JFrame,并具有定义的大小,当用户按下最大化按钮时它会缩小。

小例子:

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(); });
    }
}

预期行为:窗口最大化打开。当用户单击最大化按钮时,窗口变为未最大化,大小为 500x300 像素。

这可以正常工作

  • 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(旧版本,我知道,但是 .. 示例有效)

这不适用于

  • Windows,openjdk 12.0.1

窗口未最大化打开的位置。

setPreferredSize 调用被删除时,窗口打开最大化,但在取消最大化时缩小为“无”。

是否有任何已知的错误或解决方法? (将setPreferredSize 移动到setExtendedState 上方没有帮助)。

【问题讨论】:

  • 虽然我无法重现此处的行为(在 Windows 上的 Sun/Oracle 1.8 变体中),但我建议将 frame.setExtendedState(MAXIMIZED_BOTH); 移至 frame.pack(); 之后。这适用于您正在测试的 Open JDK 版本吗?
  • 我在 4 月 29 日提出了一个问题,并在选项卡中打开了这个问题,等待回复。当我厌倦了它弄乱了我的浏览器标签时,我关闭了它,但决定在我做之前投反对票。 (无需感谢我回答您的问题 - 不客气!)

标签: java swing jframe fullscreen


【解决方案1】:

我遇到了同样的问题,但我设法解决了。
问题是 frame.pack()。
事实上,它将框架的大小设置为其首选大小。我还注意到 Java 8(或 9)和 Java 12 之间的区别,我认为这是 openjdk 上的一个错误。

但是,要解决此问题,您应该在调用 pack() 之后调用 setExtendedState ,如下所示:

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();
        });
    }
}

【讨论】:

    【解决方案2】:

    我认为你只是误解了pack的效果:

    使此窗口的大小适合 首选大小和布局 其子组件。结果窗口的宽度和高度是 如果任一尺寸小于 上一次调用 setMinimumSize 指定的最小尺寸 方法。

    你的用例可能就是解释:

    • 您将窗口置于最大化状态,因此它的大小应该是屏幕大小减去桌面边框的大小。然而,这是特定于平台的(Windows、Linux 和我不想识别的其他操作系统 :))。
    • 您在内容窗格旁边没有任何组件,并将首选大小放在窗口上而不是其内容窗格上。 JFrame 可以委托给内容窗格,但 LayoutManager 可能会简单地忽略 preferredSize(例如,BorderLayout 忽略它,因为 CENTER 约束),同样适用于最小值(这里是 0, 0)和最大尺寸((Integer.MAX_VALUE, Integer.MAX_VALUE)(Short.MAX_VALUE, Short.MAX_VALUE))。
    • 您调用 pack,这会影响未最大化状态的大小:大小可能无效。

    Java 11 和 12 之间可能发生的变化是调整窗口大小的本机调用:它可能只是禁止您将大小更改为 (0,0) 或负值,这可能被视为 错误窗口管理器。 Java 可能会引入另一个层(例如:验证大小)。

    【讨论】:

      猜你喜欢
      • 2011-10-04
      • 1970-01-01
      • 2011-03-30
      • 2012-06-08
      • 2010-12-19
      • 2018-10-17
      • 1970-01-01
      • 2015-09-01
      • 1970-01-01
      相关资源
      最近更新 更多