【问题标题】:Adding a Set of JTextFields to a Panel at Runtime, Different Layout Manager在运行时向面板添加一组 JTextField,不同的布局管理器
【发布时间】:2014-08-17 06:44:44
【问题描述】:

我试图在单击按钮时使一组两个 JTextfields(并排)出现在面板内。问题是 Flowlayout 之类的东西会使我的文本字段到处移动(它们排成一行或一列),而 Gridlayout 使文本字段太大。我研究过 Springlayout 和 Grouplayout,但这些布局似乎没有一种在运行时添加组件的直接方法(而且代码在我看来真的很乱,如下例所示)。

这是我试图通过布局实现的示例...运行代码并注意 JTextfields 在调整窗口大小时的反应(添加字段集按钮不起作用,因为我我不确定如何使用 Grouplayout 将组件添加到面板):

GoodLayout.java

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.EmptyBorder;

public class GoodLayout extends JFrame {

    private JPanel contentPane;
    private JTextField textField;
    private JTextField textField_1;
    private JTextField textField_2;
    private JTextField textField_3;
    private JTextField textField_4;
    private JTextField textField_5;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GoodLayout frame = new GoodLayout();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public GoodLayout() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 383, 328);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(new BorderLayout(0, 0));

        JButton buttonAddFields = new JButton("+ Add Set of Fields +");
        buttonAddFields.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Add a set of fields to the panel");

            }
        });
        contentPane.add(buttonAddFields, BorderLayout.SOUTH);

        JPanel panel = new JPanel();
        contentPane.add(panel, BorderLayout.CENTER);

        textField = new JTextField();
        textField.setColumns(10);

        textField_1 = new JTextField();
        textField_1.setColumns(10);

        textField_2 = new JTextField();
        textField_2.setColumns(10);

        textField_3 = new JTextField();
        textField_3.setColumns(10);

        textField_4 = new JTextField();
        textField_4.setColumns(10);

        textField_5 = new JTextField();
        textField_5.setColumns(10);
        GroupLayout gl_panel = new GroupLayout(panel);
        gl_panel.setHorizontalGroup(
            gl_panel.createParallelGroup(Alignment.LEADING)
                .addGroup(gl_panel.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
                        .addGroup(gl_panel.createSequentialGroup()
                            .addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(ComponentPlacement.RELATED)
                            .addComponent(textField_1, GroupLayout.DEFAULT_SIZE, 518, Short.MAX_VALUE))
                        .addGroup(gl_panel.createSequentialGroup()
                            .addComponent(textField_2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(ComponentPlacement.RELATED)
                            .addComponent(textField_3, GroupLayout.DEFAULT_SIZE, 518, Short.MAX_VALUE))
                        .addGroup(gl_panel.createSequentialGroup()
                            .addComponent(textField_4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(ComponentPlacement.RELATED)
                            .addComponent(textField_5, GroupLayout.DEFAULT_SIZE, 518, Short.MAX_VALUE)))
                    .addContainerGap())
        );
        gl_panel.setVerticalGroup(
            gl_panel.createParallelGroup(Alignment.LEADING)
                .addGroup(gl_panel.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
                        .addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(textField_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(ComponentPlacement.RELATED)
                    .addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
                        .addComponent(textField_2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(textField_3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(ComponentPlacement.RELATED)
                    .addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
                        .addComponent(textField_4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(textField_5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addContainerGap(287, Short.MAX_VALUE))
        );
        panel.setLayout(gl_panel);
    }

}

上面代码中的重要一点是 actionPerformed 方法...我真的很想找到一个简单的解决方案,当单击按钮并出现一对文本字段时看起来不错(GUI 布局)。也许有更好的布局?我使用 Eclipse 插件 WindowBuilder 构建了上面的代码,并且尝试了所有看起来合理的不同布局选项。

感谢任何有关如何更好地解决此问题的想法或技巧

谢谢,丹

【问题讨论】:

    标签: java swing layout layout-manager


    【解决方案1】:

    不要丢弃GroupLayout 管理器——它是一个非常强大的布局管理器 并且是为数不多的正确做事的经理之一。 但是,它不适合动态布局结构,因为 布局的构建方式。我们将不得不完全重做我们的布局和 进行临时计算。

    为此,我们可以轻松使用MigLayoutMigLayout是第三方布局 也做事正确的经理。它易于使用且功能强大。

    package com.zetcode;
    
    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import javax.swing.AbstractAction;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import net.miginfocom.swing.MigLayout;
    
    public class GoodLayout2 extends JFrame {
    
        private JPanel pnl;
    
        public GoodLayout2() {
    
            initUI();
    
            setTitle("MigLayout solution");
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        private void initUI() {
    
            JButton addBtn = new JButton("Add");
            addBtn.addActionListener(new AddAction());
    
            pnl = new JPanel(new MigLayout("ins dialog, wrap 2"));
            pnl.add(addBtn, "span 2, center");
            pnl.add(new JTextField(10));
            pnl.add(new JTextField(10), "pushx, growx");
            pnl.add(new JTextField(10));
            pnl.add(new JTextField(10), "pushx, growx");
            pnl.add(new JTextField(10));
            pnl.add(new JTextField(10), "pushx, growx");
    
            add(pnl);
            pack();
    
        }
    
        private class AddAction extends AbstractAction {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                pnl.add(new JTextField(10));
                pnl.add(new JTextField(10), "pushx, growx");
                pnl.doLayout();
                pnl.repaint();
            }
    
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    GoodLayout2 ex = new GoodLayout2();
                    ex.setVisible(true);
                }
            });
        }
    }
    

    我已将按钮放在窗口的北部,因为代码 然后稍微不那么复杂了。

    【讨论】:

    • 非常感谢!您的代码非常可读和简洁。这完美地解决了我的问题:)
    猜你喜欢
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多