Java 确保SpringLayout不会';不要缩小到一定的尺寸以下

Java 确保SpringLayout不会';不要缩小到一定的尺寸以下,java,swing,springlayout,Java,Swing,Springlayout,我试图使用SpringLayout实现一个非常简单的UI(部分原因是,与我在网上找到的大多数教程作者不同,与其他布局管理器相比,我非常喜欢编码界面,部分原因是我想学习如何使用它)。UI基本上如下所示: 这一切都很好。如果我增加窗口大小,UI将按我想要的方式调整大小(保持欢迎文本居中,并扩展文本区域以填充所有新的可用空间)。但是,在某一点以下(更具体地说,当窗口对于欢迎文本来说太窄时): 我希望窗口不允许进一步收缩,因此,如果用户试图将窗口缩小到足以容纳组件的大小,它将停止。如何使用Sprin

我试图使用
SpringLayout
实现一个非常简单的UI(部分原因是,与我在网上找到的大多数教程作者不同,与其他布局管理器相比,我非常喜欢编码界面,部分原因是我想学习如何使用它)。UI基本上如下所示:

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

我希望窗口不允许进一步收缩,因此,如果用户试图将窗口缩小到足以容纳组件的大小,它将停止。如何使用
SpringLayout
layout管理器实现这一点

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

  • 您可以为
    TopLevelContainer

  • 您已将
    JTextArea
    放入
    JScrollPane

  • 最简单的方法是混合
    LayoutManager
    (称为
    NestedLayout
    ),将GUI拆分为多个部分(用相同或不同的
    LayoutManager
    分隔
    jpanel
    ),而不是实现一些最具特色的
    LayoutManager
    gridbagloayout
    SpringLayout
    )对于整个
    容器

  • 一些
    layoutmanager
    pretty ignore
    setXxxSize

  • SpringLayout
    不是我的拿手好戏


  • 要实现“真实”(不可收缩超过)最小尺寸,有几个问题:

    • 子组件必须返回一些合理的(基于其内容)最小大小,而许多核心组件则没有
    • 无论可用空间有多小,布局经理必须尊重所有孩子的隐私
    • 顶层容器(此处为JFrame)不得允许收缩超过最小值
    第一个是JLabel,第二个是SpringLayout(这就是标签被截断的原因)——第三个是潜在问题,解决方案并不明显,实际上在运行@mKorbel的示例之前我甚至不知道这是可能的。相关路线确实是

    frame.setMinimumSize(someSize);
    
    有了这条线,就不可能缩小下面的框架。没有,它是。从那个观察开始,一些挖掘结果显示文档在窗口中被覆盖

    将此窗口的最小大小设置为常量值。[…]如果 当前窗口的大小小于窗口的最小大小 自动放大以满足最小尺寸的要求。如果设置了大小或 setBounds方法在之后以小于宽度或高度的方式调用 […]会自动放大以符合最小大小值。 如果用户尝试调整大小,则可能会限制调整大小操作 窗口低于最小大小值。这种行为依赖于平台

    查看代码,有两个(实现,不要依赖它们:-)与最小大小相关的详细信息

     Dimension minSize;
     boolean minSizeSet;
    
    和公共api访问

     public Dimension getMinimumSize()
     public boolean isMininumSizeSet()
    
    第一个比较旧(jdk1.1),后一个比较新(jdk1.5)——这意味着第一个不能依赖于后一个,但在内部必须检查null minize。Window上重写的大小调整方法(保证尽最大努力遵守手动设置的minSize)是最新的(jdk6),并且确实依赖于后者。或者换言之:重写isMinimumSizeSet就可以做到这一点

    一些代码片段(注意:这是一种未经测试的黑客行为,很可能与操作系统有关,具有不良的副作用!):


    看,这里的问题是最小大小最终是硬编码的。我想完全避免这种情况,因此我可以在以后决定添加另一个UI元素(比如,右边的一个长而窄的列表),而不必在我的代码中重写任何元素。+1
    TextLayout
    ,如图所示,是获得最小边界的一种方法,但经过验证的首选大小应该是好的,太糟糕了。getXXSize中的硬编码大小几乎和使用setXXSize一样糟糕;-)忘记:+1检测window.setMinimumSize的大小保证(在操作系统允许的范围内)契约-直到昨天才意识到:-@kleopatra(@Andrew Thompson)bump+1的一种教训我投票选择了如此不同和有价值的答案,不可信请继续保持你答案的坚韧程度
     public Dimension getMinimumSize()
     public boolean isMininumSizeSet()
    
        // 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);