要实现“真实”(不可缩小)最小尺寸有几个问题:
- 子组件必须返回一些合理的(基于它们的内容)最小尺寸,许多核心组件不这样做
- layoutManager 必须尊重所有子项的复合最小值,无论可用空间多么小
- 顶级容器(此处为 JFrame)不得缩小超出最小值
第一个对于 JLabel 是正确的,第二个对于 SpringLayout 是正确的(这就是标签被截断的原因) - 这将第三个作为潜在问题,解决方案并不明显,实际上我不知道在运行@mKorbel 的示例之前,它甚至是可能的。相关行确实是
frame.setMinimumSize(someSize);
有了这条线,就不可能缩小下面的框架。没有,它是。从那个观察开始,一些挖掘结果证明了 Window 中覆盖的文档
将此窗口的最小尺寸设置为一个常数值。 [..] 如果
当前窗口的大小小于 minimumSize 窗口的大小
会自动放大以符合最小尺寸。如果 setSize 或
之后调用 setBounds 方法,其宽度或高度小于
[...] 会自动放大以符合 minimumSize 值。
如果用户尝试调整大小,调整大小操作可能会受到限制
窗口低于 minimumSize 值。此行为取决于平台。
看代码,有两个(实现,不要依赖它们:-)与最小尺寸相关的细节
Dimension minSize;
boolean minSizeSet;
和公共api访问
public Dimension getMinimumSize()
public boolean isMininumSizeSet()
第一个相当旧(jdk1.1),后者相当新(jdk1.5) - 暗示第一个不能依赖后者,但在内部必须检查 null minSize。 Window 上覆盖的大小调整方法(保证尽最大努力尊重手动设置的 minSize)是最新的(jdk6),do 依赖于后者。或者换句话说:覆盖 isMinimumSizeSet 就可以了。
一些代码 sn-p(注意:这是一个 hack,未经测试,很可能是依赖于操作系统的,具有不良副作用!):
// JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("some frame title") {
/**
* Overridden to tricks sizing to respect the min.
*/
@Override
public boolean isMinimumSizeSet() {
return true; //super.isMinimumSizeSet();
}
/**
* Overridden to adjust for insets if tricksing and not using
* LAF decorations.
*/
@Override
public Dimension getMinimumSize() {
Dimension dim = super.getMinimumSize();
// adjust for insets if we are faking the isMinSet
if (!super.isMinimumSizeSet() && !isDefaultLookAndFeelDecorated()) {
Insets insets = getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.bottom + insets.top;
}
return dim;
}
};
// add a component which reports a content-related min
JLabel label = new JLabel("Welcome to my application!");
// make it a big min
label.setFont(label.getFont().deriveFont(40f));
frame.add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);