Java 什么是最好的布局管理器?

Java 什么是最好的布局管理器?,java,swing,layout-manager,Java,Swing,Layout Manager,我想制作一个类似上面的gui。现在我有一个面板,上面有姓名标签、姓名文本字段、生日日期标签和生日文本字段。我的问题是,在面板上使用哪种布局管理器最好,以便“名称组件”(标签+文本字段)行和“出生日期组件”(标签+文本字段)行在面板中垂直均匀分布 我考虑过使用流布局,但这将导致两行组件之间没有间隙。我考虑过使用网格布局,但我不知道两行组件之间的间隙大小 一个更复杂的方法…我考虑将姓名标签和文本字段放在一个面板中,将出生日期标签和文本字段放在另一个面板中,然后制作基本面板边框布局,并将姓名设置为no

我想制作一个类似上面的gui。现在我有一个面板,上面有姓名标签、姓名文本字段、生日日期标签和生日文本字段。我的问题是,在面板上使用哪种布局管理器最好,以便“名称组件”(标签+文本字段)行和“出生日期组件”(标签+文本字段)行在面板中垂直均匀分布

我考虑过使用流布局,但这将导致两行组件之间没有间隙。我考虑过使用网格布局,但我不知道两行组件之间的间隙大小

一个更复杂的方法…我考虑将姓名标签和文本字段放在一个面板中,将出生日期标签和文本字段放在另一个面板中,然后制作基本面板边框布局,并将姓名设置为north,出生日期在南方…但是我仍然需要确保名字组件在名字面板中垂直居中,出生日期组件在出生日期面板中垂直居中

感谢您的帮助。目标是确保名称组件行和出生日期组件行垂直展开,名称组件在上半部分垂直居中,出生日期组件在下半部分垂直居中。如果有什么听起来让人困惑,请告诉我,我会尝试重新措辞,以便更好地理解

我在eclipse中严格使用Java swing,没有GUI构建器或类似的东西。

我个人喜欢

下面是一个示例来演示:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class Test {

    private JFrame frame;
    private JTextField nameTextField, birthDateTextField;
    private JLabel nameLabel, birthDateLabel;

    public Test() {
        initComponents();
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }
                } catch (Exception e) {
                    // If Nimbus is not available, you can set the GUI to another look and feel.
                }
                new Test();
            }
        });
    }

    private void initComponents() {
        frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new GridBagLayout());

        nameTextField = new JTextField(30);
        birthDateTextField = new JTextField(30);
        nameLabel = new JLabel("Name:");
        birthDateLabel = new JLabel("Birth Date:");

        GridBagConstraints gc = new GridBagConstraints();
        gc.fill = GridBagConstraints.HORIZONTAL;
        gc.insets = new Insets(10, 10, 10, 10);

        gc.gridx = 0;
        gc.gridy = 0;
        frame.add(nameLabel, gc);

        gc.gridx = 1;
        gc.gridy = 0;
        frame.add(nameTextField, gc);

        gc.gridx = 0;
        gc.gridy = 1;
        frame.add(birthDateLabel, gc);

        gc.gridx = 1;
        gc.gridy = 1;
        frame.add(birthDateTextField, gc);

        frame.pack();
        frame.setVisible(true);
    }
}


适合你的需要。看一看。它能够自动创建间隙(或者您可以自己管理间隙),非常适合创建表单。它可以水平工作,也可以垂直工作。

我强烈建议您不要使用由布局管理器自动设计的布局——它们可以灵活,但往往被用作锤子,如果您希望以自然方式调整组件的大小,这是一个非常棘手的问题,需要非常精细的处理

学习使用布局管理器是一门艺术。您不会只选择一种类型并将其用于每个问题,而是选择几种不同的类型,并以类似于您的数据的方式嵌套它们

在您的情况下,我认为您可以很好地使用3个流布局,两个水平布局包含在一个垂直布局中,这种GUI正是flowLayout的用途,您不必添加任何参数

顺便说一句,许多问题可以通过嵌套边界和流布局来解决——边界非常有用,因为中间的行为方式可以占用尽可能多的空间,但留下4个边所需的空间——事实上,边界布局通常只填充2或3个区域——但可以很容易地嵌套其他边界或流布局。这些导致GUI只需要很少的位置细节,但仍然可以自然调整大小

编辑: 下面是嵌套在长方体布局中的两个流布局的一些工作代码

它是groovy(不是java),但区别在于纯粹的语法——更少的混乱

请注意,简单且缺乏数字可供发明——它的工作原理与您预期的非常相似

import javax.swing.* import java.awt.* f=new JFrame() f.setSize(300,200) p=f.getContentPane() p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)) p.add(panel("Button 1")) p.add(panel("Button 2")) f.show() void addPanel(name) { def child=new JPanel() child.add(new JButton(name)) child.add(new JTextField(20)) return child } 导入javax.swing* 导入java.awt* f=新JFrame() f、 设置大小(300200) p=f.getContentPane() p、 setLayout(新的BoxLayout(p,BoxLayout.Y_轴)) p、 添加(面板(“按钮1”)) p、 添加(面板(“按钮2”)) f、 show() void addPanel(名称){ def child=new JPanel() 添加(新的JButton(名称)) 添加(新JTextField(20)) 返回儿童 } 我喜欢这个。在这种情况下,布局组件将非常容易,因为MigLayout具有类似表格的行为,并且组件将以这种方式排列。这在中进行了描述

编辑:

下面是一个小例子:

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;

public class Test {

    private JFrame frame;
    private JTextField nameTextField, birthDateTextField;
    private JLabel nameLabel, birthDateLabel;

    public Test() {
        initComponents();
    }

    public static void main(String args[]) {
        new Test();
    }

    private void initComponents() {
        frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new MigLayout());

        nameTextField = new JTextField(30);
        birthDateTextField = new JTextField(30);
        nameLabel = new JLabel("Name:");
        birthDateLabel = new JLabel("Birth Date:");

        frame.add(nameLabel);
        frame.add(nameTextField, "wrap");
        frame.add(birthDateLabel);
        frame.add(birthDateTextField);
        frame.pack();
        frame.setVisible(true);
    }
}


当然,使用JGoodies的FormLayout可以实现这一点,但JDK中不包括这一点。我不同意。许多内置的Swing布局管理器都非常适合以这种方式使用。但是,一个简洁、功能齐全的布局管理器,如MigLayout(由htz推荐),肯定会允许您使用单一的布局来满足您的所有需求,并且仍然可以提供可预测且简单的规则,以允许以自然的方式调整大小。我同意这两种观点。我只是一个学习GUI的初学者…虽然我可以使用嵌套布局设计GUI(这让我的思维有点像拼图),但如果我能用一个布局完成所有工作,我有时会很高兴MigLayout真的是一个很好的管理器,但我同意Bill K的观点,混合不同的裁员经理可以获得最好的结果。我通常使用MigLayout,但有时需要另一个管理器,当您希望代码尽可能简单时。我在一些极其复杂的UI上专业地使用了MigLayout,它处理了我抛出的所有内容。这非常有趣。我以前从来没有听说过它,但它看起来会让设计布局变得更容易。不幸的是,我喜欢你的答案,但另一个家伙看起来在演示上花了很多精力,所以我放弃了你的答案,给了他一个复选标记。在这种情况下,我会推荐布局列表中的最后一个。+1这是一件事,
GroupLayout
做得很好,例如。@Eddie To使用起来很复杂,会导致代码混乱。Mig和GridBag使用起来要好得多。@Anthony所以你建议OP转到JDK中没有提供的
LayoutManager
来完成这么简单的任务,因为这是一个假设的情况?在这种情况下,大多数人都会被否决(而你的否决票是因为你的观点不同?!剥猫皮的方法很多),单一的解决方案不能涵盖所有的可能性。这符合OP的要求,并与JDK:P结合在一起,不,除非你有0 logicI个人喜欢GridBagLayout-你必须是受虐狂:-)哪些布局是完全跨平台的。在工作中,我们通常