使用哪种布局管理器?

时间:2012-11-05 19:22:35

标签: java swing user-interface layout layout-manager

GUI

所以基本上我想创建这种GUI,但由于我对Java GUI缺乏经验,我无法弄清楚要使用哪种布局管理器。我已经尝试过Flow,Border,Grid,但是没有一个允许我创建这种GUI而不会弄乱某处的路线。

有什么建议吗?我将来如何决定布局管理器,还是会有经验带来的东西?

我更喜欢使用简单易用的布局,因为这是一个非常基本的GUI,我认为不应该像MiGLayout这样的东西。

4 个答案:

答案 0 :(得分:3)

我会使用复合面板和布局的组合。除了更容易使布局工作之外,您还可以在自己的班级中隔离责任区域。

enter image description here

public class TestLayout13 {

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

    public TestLayout13() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new FormPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class FormPane extends JPanel {

        public FormPane() {
            setBorder(new EmptyBorder(8, 8, 8, 8));
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.weightx = 1;

            NamePane namePane = new NamePane();
            namePane.setBorder(new CompoundBorder(new TitledBorder("Name"), new EmptyBorder(4, 4, 4, 4)));
            add(namePane, gbc);

            gbc.gridy++;

            EMailPane emailPane = new EMailPane();
            emailPane.setBorder(new CompoundBorder(new TitledBorder("E-Mail"), new EmptyBorder(4, 4, 4, 4)));
            add(emailPane, gbc);
        }

    }

    public class NamePane extends JPanel {

        public NamePane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.EAST;

            add(new JLabel("First Name:"), gbc);
            gbc.gridx += 2;
            add(new JLabel("Last Name:"), gbc);
            gbc.gridy++;
            gbc.gridx = 0;
            add(new JLabel("Title:"), gbc);
            gbc.gridx += 2;
            add(new JLabel("Nickname:"), gbc);

            gbc.gridx = 1;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.anchor = GridBagConstraints.WEST;
            gbc.weightx = 0.5;
            add(new JTextField(10), gbc);
            gbc.gridx += 2;
            add(new JTextField(10), gbc);
            gbc.gridy++;
            gbc.gridx = 1;
            add(new JTextField(10), gbc);
            gbc.gridx += 2;
            add(new JTextField(10), gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.anchor = GridBagConstraints.EAST;
            gbc.weightx = 0;
            gbc.fill = GridBagConstraints.NONE;
            add(new JLabel("Format:"), gbc);

            gbc.anchor = GridBagConstraints.WEST;
            gbc.gridx++;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(new JComboBox(), gbc);            
        }        
    }

    protected class EMailPane    extends JPanel {

        public EMailPane() {
            JPanel detailsPane = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.EAST;
            detailsPane.add(new JLabel("E-Mail Address:"), gbc);

            gbc.gridx++;
            gbc.anchor = GridBagConstraints.WEST;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            detailsPane.add(new JTextField(10), gbc);

            gbc.gridy++;
            gbc.gridx = 0;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.weighty = 1;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            detailsPane.add(new JScrollPane(new JList()), gbc);

            JPanel buttonsPane = new JPanel(new GridBagLayout());
            gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;

            buttonsPane.add(new JButton("Add"), gbc);
            gbc.gridy++;
            buttonsPane.add(new JButton("Edit"), gbc);
            gbc.gridy++;
            buttonsPane.add(new JButton("Delete"), gbc);

            gbc.gridy++;
            gbc.weighty = 1;
            gbc.anchor = GridBagConstraints.NORTH;
            buttonsPane.add(new JButton("As Default"), gbc);

            JPanel formatPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
            formatPane.setBorder(new TitledBorder(new EmptyBorder(1, 1, 1, 1), "Mail Format:"));
            formatPane.add(new JRadioButton("HTML"));
            formatPane.add(new JRadioButton("Plain"));
            formatPane.add(new JRadioButton("Custom"));

            setLayout(new BorderLayout());
            add(detailsPane);
            add(buttonsPane, BorderLayout.LINE_END);
            add(formatPane, BorderLayout.PAGE_END);                
        }            
    }        
}

答案 1 :(得分:2)

我的偏好是MigLayout,因为它是Swing最完整且记录良好的布局管理器。除了Swing之外,它还支持SWT和JavaFX,因此您花在学习它上面的时间可能不止一次。它支持maven,有关详细信息,请参阅http://www.miglayout.com,这是一个很大的优点。它还有一个非常有用的调试功能。您可以在构造函数中添加“debug 1”,然后您将了解如何创建布局。例如:

emailButtonPanel.setLayout(new MigLayout("wrap, fill, insets 20 10 0 10, debug 1"));

我不时发现非常有用的另一个功能是hidemode,它允许您在不可见的情况下(或其他几种策略)组件不参与布局。

以下是使用MigLayout发布的图片的一种可能方法:

Layout using MigLayout

import java.awt.*;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

import net.miginfocom.layout.CC;
import net.miginfocom.swing.MigLayout;

/**
 */
public class LayoutApproach {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Contact information");
                frame.getContentPane().add(new ContactPanel());
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setMinimumSize(new Dimension(800, 450));
                frame.setLocationRelativeTo(null); // Center
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    static class ContactPanel extends JPanel {

        private JPanel namePanel;
        private TitledBorder nameTitledBorder;
        private JLabel firstNameLabel;
        private JTextField firstNameTextField;

        private JLabel lastNameLabel;
        private JTextField lastNameTextField;

        private JLabel titleLabel;
        private JTextField titleTextField;

        private JLabel nicknameLabel;
        private JTextField nickNameTextField;

        private JLabel formatLabel;
        private JComboBox<String> formatComboBox;

        private JPanel emailPanel;
        private TitledBorder emailTitledBorder;
        private JLabel emailLabel;
        private JTextField emailTextField;
        private JList<String> emailItemsList;
        private JLabel mailFormatLabel;
        private JPanel emailButtonPanel;
        private JButton addButton;
        private JButton editButton;
        private JButton removeButton;
        private JButton asDefaultButton;

        private JRadioButton htmlRadioButton;
        private JRadioButton plainTextRadioButton;
        private JRadioButton customTextRadioButton;

        private JPanel buttonPanel;

        private JButton okButton;
        private JButton cancelButton;

        public ContactPanel() {
            createComponents();
            makeLayout();
            createHandlers();
            registerHandlers();
            initComponent();
            i18n();
        }

        /**
         * Create GUI components, but contains no layout.
         */
        public void createComponents() {

            namePanel = new JPanel();
            nameTitledBorder = new TitledBorder("");
            firstNameLabel = new JLabel();
            firstNameTextField = new JTextField();
            lastNameLabel = new JLabel();
            lastNameTextField = new JTextField();
            titleLabel = new JLabel();
            titleTextField = new JTextField();
            nicknameLabel = new JLabel();
            nickNameTextField = new JTextField();
            formatLabel = new JLabel();
            formatComboBox = new JComboBox<>();

            emailPanel = new JPanel();
            emailTitledBorder = new TitledBorder("");
            emailLabel = new JLabel();
            emailTextField = new JTextField();
            emailItemsList = new JList<>();
            mailFormatLabel = new JLabel();
            emailButtonPanel = new JPanel();
            addButton = new JButton();
            editButton = new JButton();
            removeButton = new JButton();
            asDefaultButton = new JButton();

            htmlRadioButton = new JRadioButton();
            plainTextRadioButton = new JRadioButton();
            customTextRadioButton = new JRadioButton();

            buttonPanel = new JPanel();
            okButton = new JButton();
            cancelButton = new JButton("Cancel");
        }

        /**
         * Create listeners/handlers
         */
        public void createHandlers() {
        }

        /**
         * Registers/adds listeners/handlers.
         */
        public void registerHandlers() {
        }

        public void makeLayout() {
            layoutNamePanel();
            layoutEmailPanel();
            layoutButtonPanel();

            MigLayout migLayout = new MigLayout("fill, insets 20");
            setLayout(migLayout);
            add(namePanel, "dock north");
            add(emailPanel, "dock north");
            add(buttonPanel, "dock south");
        }

        private void layoutButtonPanel() {
            buttonPanel.setLayout(new MigLayout("alignX right"));
            buttonPanel.add(okButton, "tag ok");
            buttonPanel.add(cancelButton, "tag cancel");
        }

        private void layoutNamePanel() {
            MigLayout nameLayout = new MigLayout("fill, wrap 4",               // Layout Constraints
                                                 "15[]15[grow]15[]15[grow]",   // Column constraints
                                                 "");                          // Row constraints

            // -- Layout all components with name
            namePanel.setLayout(nameLayout);
            // Create this border here since I use it for layout
            Border nameBorder = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 6, 10, 6), nameTitledBorder);
            namePanel.setBorder(nameBorder);
            namePanel.add(firstNameLabel, "alignX right");
            namePanel.add(firstNameTextField, "grow");
            namePanel.add(lastNameLabel, "alignX right");
            namePanel.add(lastNameTextField, "grow");

            namePanel.add(titleLabel, "alignX right");
            namePanel.add(titleTextField, "grow");
            namePanel.add(nicknameLabel, "alignX right");
            namePanel.add(nickNameTextField, "grow");

            namePanel.add(formatLabel, "alignX right");
            namePanel.add(formatComboBox, new CC().grow().span(3));  // Alternative to using plain text'
        }

        private void layoutEmailPanel() {
            MigLayout emailLayout = new MigLayout("fill",// Layout Constraints
                                                  "",    // Column constraints
                                                  "");   // Row constraints

            // -- Layout all components with name
            emailPanel.setLayout(emailLayout);
            // Create this border here since I use it for layout
            Border emailBorder = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 6, 10, 6), emailTitledBorder);
            emailPanel.setBorder(emailBorder);

            emailButtonPanel.setLayout(new MigLayout("wrap, fill, insets 20 10 0 10"));
            emailButtonPanel.add(addButton, "growx");
            emailButtonPanel.add(editButton, "growx");
            emailButtonPanel.add(removeButton, "growx");
            emailButtonPanel.add(asDefaultButton, "growx");

            JPanel emailAndItems = new JPanel(new MigLayout("fill"));
            emailAndItems.add(emailLabel, "split 2");
            emailAndItems.add(emailTextField, "span, growx, wrap");
            emailAndItems.add(emailItemsList, "span, grow");

            JPanel radioButtons = new JPanel(new MigLayout());
            radioButtons.add(htmlRadioButton);
            radioButtons.add(plainTextRadioButton);
            radioButtons.add(customTextRadioButton);

            emailPanel.add(radioButtons, "dock south");
            emailPanel.add(mailFormatLabel, "dock south, gapleft 15");
            emailPanel.add(emailAndItems, "dock west, growx, push");
            emailPanel.add(emailButtonPanel, "dock east, shrink");

            ButtonGroup buttonGroup = new ButtonGroup();
            buttonGroup.add(htmlRadioButton);
            buttonGroup.add(plainTextRadioButton);
            buttonGroup.add(customTextRadioButton);
        }

        /**
         * Sets initial values for component.
         */
        public void initComponent() {
            formatComboBox.addItem("Item 1");
            formatComboBox.addItem("Item 2");
            formatComboBox.addItem("Item 3");
            formatComboBox.addItem("Item 4");

            DefaultListModel<String> model = new DefaultListModel<>();
            emailItemsList.setModel(model);
            model.insertElementAt("Item 1", 0);
            model.insertElementAt("Item 2", 1);
            model.insertElementAt("Item 3", 2);
            model.insertElementAt("Item 4", 3);

            customTextRadioButton.setSelected(true);
        }

        public void i18n() {
            nameTitledBorder.setTitle("Name:");
            firstNameLabel.setText("First Name:");
            lastNameLabel.setText("Last Name:");
            titleLabel.setText("Title:");
            nicknameLabel.setText("Nickname:");
            formatLabel.setText("Format:");

            emailTitledBorder.setTitle("E-mail");
            emailLabel.setText("E-mail address:");
            mailFormatLabel.setText("Mail Format:");
            addButton.setText("Add");
            editButton.setText("Edit");
            removeButton.setText("Remove");
            asDefaultButton.setText("As Default");

            htmlRadioButton.setText("HTML");
            plainTextRadioButton.setText("Plain Text");
            customTextRadioButton.setText("Custom");

            okButton.setText("OK");
            cancelButton.setText("Cancel");
        }
    }
}

代码是用Java 7编写的。与它一起使用的maven pom.xml文件可能是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>stackoverflow</groupId>
    <artifactId>stackoverflow</artifactId>
    <version>1.0</version>


    <dependencies>
        <dependency>
            <groupId>com.miglayout</groupId>
            <artifactId>miglayout-core</artifactId>
            <version>4.2</version>
        </dependency>

        <dependency>
            <groupId>com.miglayout</groupId>
            <artifactId>miglayout-swing</artifactId>
            <version>4.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

答案 2 :(得分:1)

如果您正在寻找Java库布局管理器,我会说边框布局可以正常工作。更高级的是米格布局。你可以谷歌搜索信息。

你知道你可以嵌套布局经理吗?同样,一个JPanel有一个布局管理器,另一个有不同的布局管理器。所以可以有边框布局和另一种流布局。

答案 3 :(得分:0)

如果您想要一个简单的Swing设计器,可以尝试NetBeans,但是IMHO Miglayout是按照您的意图完成UI的最短方式。在最初的学习曲线之后......当然......

尝试在网格中显示您的屏幕,然后您可以同时使用gridbag和miglayout。