【问题标题】:Variable Layout in SwingSwing 中的可变布局
【发布时间】:2011-03-11 15:01:49
【问题描述】:

当您不知道您将拥有多少组件以及它们有多大时,您将如何生成一个看起来不错的 gui?

例如,用户输入他们想要多少个文本字段以及这些文本字段中的哪些被分组在有边框的面板中,程序会生成这个。

我一直在使用 GridLayout,但问题是它使所有单元格具有相同的宽度和高度,当所有组件具有相同的大小时这很好,但是当我有一个文本字段和一个边框时具有多个字段的面板,文本字段被拉伸或面板被挤压。

我希望所有组件都具有最小尺寸,但您知道,它们仍然可用。

Example of how it is now, using GridLayout,所有字段都是正常的,单行JTextFields,其中标题为日期的面板被完全挤压(它有三个字段),第一级字段很大。有没有人指点一下?

【问题讨论】:

    标签: java swing layout


    【解决方案1】:

    MiGLayout 有很大的吸引力,但BoxLayout 是一个替代方案。

    import java.awt.*;
    import java.util.List;
    import java.util.ArrayList;
    import javax.swing.*;
    
    public class BoxTest extends JPanel {
    
        private List<JTextField> fields = new ArrayList<JTextField>();
    
        public BoxTest() {
            this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            this.add(createPane(3, "One ", Color.red));
            this.add(createPane(3, "Two ", Color.green));
            this.add(createPane(10, "Three ", Color.blue));
        }
    
        private JPanel createPane(int n, String s, Color c) {
            JPanel outer = new JPanel();
            outer.setLayout(new BoxLayout(outer, BoxLayout.Y_AXIS));
            outer.setBorder(BorderFactory.createLineBorder(c, 2));
            for (int i = 0; i < n; i++) {
                JPanel inner = new JPanel();
                inner.setLayout(new BoxLayout(inner, BoxLayout.X_AXIS));
                JLabel label = new JLabel(s + i + ":", JLabel.RIGHT);
                label.setPreferredSize(new Dimension(80, 32));
                inner.add(label);
                JTextField tf = new JTextField("Stackoverflow!", 32);
                inner.add(tf);
                fields.add(tf);
                outer.add(inner);
            }
            return outer;
        }
    
        private void display() {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JScrollPane jsp = new JScrollPane(this,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            this.validate();
            Dimension d = this.getPreferredSize();
            d.height /= 2;
            jsp.getViewport().setPreferredSize(d);
            jsp.getVerticalScrollBar().setUnitIncrement(
                this.getPreferredSize().height / fields.size());
            f.add(jsp);
            f.pack();
            f.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new BoxTest().display();
                }
            });
        }
    }
    

    【讨论】:

    • 我现在唯一的问题是,当一个框中的标签不同时,文本框的大小也不同,就像 grab.by/5gpW 一样。有没有办法在不编写我自己的 LayoutManager 的情况下解决这个问题?
    • @thepandaatemyface:我更新了示例以展示一种方法。
    • @mKorbel 使用 mot juste:设置标签的首选大小是一种任意技巧。更精确的方法可能是使用here 讨论的技术之一找到最长的标签。
    • +1 - 虽然我怀疑这对于GroupLayout 来说也是一个很好的例子,因为它不必设置标签的大小。
    • @AndrewThompson:好点;另请参阅此 example 使用 GroupLayout
    【解决方案2】:

    我会看看 miglayout。它比任何内置的布局管理器都要有用得多。

    【讨论】:

      【解决方案3】:

      您的总体目标 - “可用组件大小”与“未知数”发生冲突。使数字足够大,它们将不适合任何屏幕。

      如果将 JTables(单元格可编辑)与 JScrollPanel 结合使用会不会更好。 如果您想/必须保持生成组件的方法,请将包含您的组件的整个 JPanel 放入 JScrollPane 中,这样组件就不会被严重挤压。

      【讨论】:

        【解决方案4】:

        是的,MiGLayout 很好。你几乎可以用它做任何事情。

        【讨论】:

          【解决方案5】:

          AWT 和 Swing 中的最小尺寸通常是没有意义的。我建议添加一个面板以将最小尺寸委托给原始首选尺寸,并可能在新的首选尺寸上添加一点。在GridBagLayout 中,在您希望额外空间以正常尺寸放置的地方添加权重。正如 Durandal 所提到的,在顶级窗口周围弹出滚动条比挤压布局或离开屏幕要好(我在上网本上写这个,所以我知道窗口大于屏幕)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-11-25
            • 1970-01-01
            • 2012-01-29
            • 2019-04-04
            • 2018-05-03
            • 2014-12-20
            • 1970-01-01
            • 2018-05-02
            相关资源
            最近更新 更多