确保SpringLayout不会缩小到一定的大小

时间:2012-01-03 22:07:38

标签: java swing springlayout

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

UI template

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

UI when shrunk

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

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

2 个答案:

答案 0 :(得分:3)

  1. 您可以覆盖MinimumSize

  2. TopLevelContainer
  3. 您已将JTextArea添加到JScrollPane

  4. 最简单的方法是通过将GUI拆分为部分(使用相同或不同的LayoutManagers分隔NestedLayout)来混合JPanels(称为LayoutManager),而不是为整个LayoutManager

  5. 实施一些最软化的GridBagLayoutSpringLayoutContainer
  6. 某些LayoutManagers非常忽略setXxxSize

  7. SpringLayout不是我的一杯Java

  8. 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);
        }
    }
    

答案 1 :(得分:2)

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

  • 子组件必须返回一些合理的(基于其内容)最小大小,许多核心组件不
  • 无论空间有多小,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就可以了。

一些代码片段(注意:这是一个黑客,未经测试,很可能是操作系统依赖于不良副作用!):

    // 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);
相关问题