2

我正在尝试使用SpringLayout(部分是因为我,与我在网上找到的大多数教程作者相反,与其他布局管理器相比,非常像编码界面,部分是因为我想学习如何使用它) . UI 基本上是这样的:

用户界面模板

这一切都很好。如果我增加窗口大小,UI 会按照我想要的方式调整大小(保持欢迎文本居中并扩展文本区域以填充所有新的可用空间)。但是,低于某个点(更具体地说,当窗口对于欢迎文本变得太窄时):

缩小时的 UI

我希望窗口不允许进一步缩小,这样如果用户试图将窗口缩小到小于足以容纳组件的大小,它就会停止。如何使用SpringLayout布局管理器完成此操作?

我知道我可以通过处理一些调整大小事件并检查是否达到最小尺寸来做到这一点,然后将尺寸设置为最小尺寸。但这需要我 a) 知道或知道如何计算窗口的最小尺寸,甚至在它呈现之前,b) 编写一堆事件处理代码只是为了让一些 UI 呈现正确,并且 c) 编写一个我希望一个好的布局管理器能够处理的一堆代码;)

4

2 回答 2

3
  1. 你可以MinimumSize覆盖TopLevelContainer

  2. 你已经JTextAreaJScrollPane

  3. 最简单的方法是通过将 GUI 拆分为各个部分(用相同或不同分隔)来混合LayoutManagers(称为 as ) ,而不是为整体实现一些最复杂的(或)NestedLayoutJPanelsLayoutManagerLayoutManagerGridBagLayoutSpringLayoutContainer

  4. 一些LayoutManagers相当忽视setXxxSize

  5. SpringLayout不是我的 Java 杯

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

public class MinSizeForContainer {

    private JFrame frame = new JFrame("some frame title");

    public MinSizeForContainer() {
        JTextArea textArea = new JTextArea(15, 30);
        JScrollPane scrollPane = new JScrollPane(textArea);

        CustomJPanel fatherPanel = new CustomJPanel();
        fatherPanel.setLayout(new SpringLayout());

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(fatherPanel, BorderLayout.CENTER);
        frame.setLocation(20, 20);
        frame.setMinimumSize(fatherPanel.getMinimumSize());
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                MinSizeForContainer Mpgp = new MinSizeForContainer();
            }
        });
    }
}

class CustomJPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(400, 400);
    }
}
于 2012-01-03T22:36:41.760 回答
3

实现“真实”(不可缩小)最小尺寸有几个问题:

  • 子组件必须返回一些合理的(基于它们的内容)最小尺寸,许多核心组件没有
  • 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);
于 2012-01-05T14:28:31.480 回答