首页 > 解决方案 > 在 Swing 中设置 JFrame 的最小尺寸

问题描述

我希望你今天过得愉快。


注意:我发现了这个问题 - 高 DPI 缩放。由于我的计算机将所有内容缩放到 250%,setMinimumSize因此无法正常工作。是关于它的错误报告。有没有人有一个使用的解决方法addComponentListener(推理如下)。


今天,当我尝试更改JFrame窗口的最小尺寸时,我正在处理一个 Java Swing 项目。起初,我尝试了frame.setMinimumSize(new Dimension(500, 500));. 问题是(我认为这与我的屏幕尺寸有关)它确实起到了一定的作用,但它会让我调整窗口的大小小于500, 500(窗口将停止调整大小约为100像素)。

编辑:这是我用来测试的代码:

import javax.swing.*;
import java.awt.*;

class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(new Dimension(500, 500));

        frame.pack();
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}

这是我调整框架大小时发生的情况:

使用 setMinimumSize()

在我用谷歌搜索之后,我发现你可以做这个巧妙的小技巧(这只是出现的相同代码的许多版本之一):

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(new Dimension(500, 500));
        frame.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent evt) {
                Dimension size = frame.getSize();
                Dimension min = frame.getMinimumSize();
                frame.setSize((int) Math.max(min.getHeight(), size.getHeight()),
                        (int) Math.max(min.getWidth(), size.getWidth()));
            }
        });

        frame.pack();
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}

这是我调整大小时发生的情况:

使用 addComponentListener()

这样做的问题是(即使它有效),当我尝试调整大小超过最小尺寸时它会出现很多故障,因为它不够快,无法在用户调整大小之前将其改回。

经过更多的谷歌搜索,我在这里发现了一个错误报告。我从评论中试用了这段代码(是的,我确实编辑了它以使用Math.max):

import javax.swing.*;
import java.awt.*;

class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test") {
            @Override
            public Dimension getPreferredSize()
            {
                Dimension pSize = super.getPreferredSize();
                Dimension mSize = getMinimumSize();
                int wid, ht;

                wid = Math.max(pSize.width, mSize.width);
                ht = Math.max(pSize.height, mSize.height);
                return new Dimension(wid, ht);
            }
        };

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(new Dimension(500, 500));

        frame.pack();
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}

这对窗口没有影响(它的行为与第一个setMinimumSize技巧完全一样)。

编辑 2:我也试过这个(正如@camickr 建议的那样):

import javax.swing.*;
import java.awt.*;

class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(new Dimension(500, 500));

        frame.setSize(750, 750);
        frame.setVisible(true);
    }
}

但它给出的输出与第一个技巧 ( setMinimumSize) 相同。

我还删除了所有setPreferredSize行,因为没有布局管理器(更多信息在这里)。

我正在使用 Windows 10 和 JDK v13.0.2 - 这是来自以下的输出java -version

java version "13.0.2" 2020-01-14
Java(TM) SE Runtime Environment (build 13.0.2+8)
Java HotSpot(TM) 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)

以及来自的输出javac -version

javac 13.0.2

编辑 3:我最近尝试使用 JDK 11,但它给出了与 JDK 13 相同的结果(看起来这是特定于计算机/平台的)。

有谁知道解决这个问题的方法?

标签: javaswingjframe

解决方案


推荐阅读