实现“真实”(不可缩小)最小尺寸有几个问题:
- 子组件必须返回一些合理的(基于它们的内容)最小尺寸,许多核心组件没有
- 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)并且确实依赖于后者。或者换句话说:覆盖 isMinimumSizeSet 就可以了。
一些代码片段(请注意:这是一个 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);