简体   繁体   English

在运行时,使用不同的布局管理器将一组JTextField添加到面板

[英]Adding a Set of JTextFields to a Panel at Runtime, Different Layout Manager

I am trying to make a set of two JTextfields (side by side) appear inside of a panel when a button is clicked. 我试图在单击按钮时使一组两个JTextfield(并排)出现在面板内部。 The problem is that something like Flowlayout will make my textfields move all over the place (they line up in a single row or column), and Gridlayout makes the textfields far too big. 问题是像Flowlayout之类的东西会使我的文本字段到处移动(它们在一行或一列中排成一行),而Gridlayout使文本字段太大。 I have investigated Springlayout and Grouplayout, but these layouts don't seem to have a straightforward way to add a component at runtime (plus the code is really messy looking to me, as seen in the example below). 我研究了Springlayout和Grouplayout,但是这些布局似乎没有在运行时添加组件的直接方法(再加上代码对我来说真的很混乱,如下面的示例所示)。

This is an example of what I am trying to achieve with the layout...run the code and pay attention to how the JTextfields react when you resize the window (the add set of fields button doesn't work, because I am unsure of how to add components to the panel with the Grouplayout in place): 这是我尝试使用布局实现的示例...运行代码,并注意调整窗口大小时JTextfields的反应(添加字段集按钮无效,因为我不确定如何使用Grouplayout将组件添加到面板中):

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

}

The important bit in the code above is the actionPerformed method...I would really like to find a simple solution that looks good (GUI layout-wise) when the button is clicked and a pair of textfields appear. 上面代码中的重要部分是actionPerformed方法...我真的很想找到一个简单的解决方案,当单击按钮并出现一对文本字段时,该解决方案看起来不错(在GUI布局上)。 Maybe there is a better layout for this? 也许对此有更好的布局? I used the Eclipse plugin WindowBuilder to build the code above, and I have tried all of the different layout options that seemed reasonable to try. 我使用Eclipse插件WindowBuilder构建了上面的代码,并且尝试了所有似乎合理的布局选项。

Any ideas or tricks about how to better tackle this problem are appreciated 任何有关如何更好地解决此问题的想法或技巧都值得赞赏

Thanks, Dan 谢谢,丹

Do not discard the GroupLayout manager -- it is a very capable layout manager and is one of the few managers that does things properly. 不要丢弃GroupLayout管理器-它是一个功能强大的布局管理器,并且是少数可以正确执行任务的管理器之一。 However, it is not suited for dynamic layout constructions due to the way the layout is built. 但是,由于布局的构建方式,它不适用于动态布局构造。 We would have to completely redo our layout and do ad hoc calculations. 我们将不得不完全重做布局并进行临时计算。

For this, we can easily use MigLayout . 为此,我们可以轻松使用MigLayout MigLayout is a third-party layout manager that also does things properly. MigLayout是第三方布局管理器,也可以正确执行操作。 It is easy to use and very powerful. 它易于使用且功能强大。

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

I have placed the button to the north part of the window, since the code is then slightly less complicated. 我将按钮放置在窗口的北部,因为代码变得不那么复杂了。

布局好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM