在Swing框架中动态添加和删除按钮

时间:2014-11-17 12:22:53

标签: java swing jbutton jtextfield

我正在开发一个swing应用程序。我有JFrame动态添加JTextfieldJButton按钮点击。如果用户点击相同的按钮,则删除创建的组件。

在下面的屏幕图像中,当用户点击ADD按钮时,添加了新行,并且文本更改为REMOVE,就像在第二张图像中一样。

enter image description here

添加了新行,之前的按钮文字更改为REMOVE。

enter image description here

现在,如果我单击REMOVE按钮,则新添加的行必须处理,然后按钮必须再次将文本更改为ADD。

我已经尝试过添加组件,但我坚持要删除新添加的行。

任何人都可以指导我实现这一目标。

以下是我的代码。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.ArrayList;
 import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ButtonAddDynamic implements ActionListener {

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new ButtonAddDynamic().createAndShowGUI();
        }
    });
}

private JFrame frame;
private JPanel panel = new JPanel(new GridBagLayout());
private GridBagConstraints constraints = new GridBagConstraints();

private List fields = new ArrayList();
private List fieldButton = new ArrayList();
private List fieldFile = new ArrayList();

private static int countReport = 0;
String files = null;
int y = 2;

protected void createAndShowGUI() {
    try {
        UIManager
                .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
    } catch (InstantiationException ex) {
        ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    } catch (IllegalAccessException ex) {
        ex.printStackTrace();
    }

    String[] labels = { "VALIDATION FORM" };
    for (String label : labels)
        addColumn(label);

    frame = new JFrame("Add Button Dynamically");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(new JScrollPane(panel));
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    // Set the default button to button1, so that when return is hit, it
    // will hit the button1

    frame.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent we) {
            System.exit(0);
        }
    });
}

private void addColumn(String labelText) {
    constraints.gridx = fields.size();
    constraints.gridy = 1;
    panel.add(new JLabel(labelText), constraints);
    constraints.gridy = 2;
    final JTextField field = new JTextField(40);
    field.setEditable(false);
    panel.add(field, constraints);
    fields.add(field);

    // constraints.gridy=3;
    constraints.gridx = fields.size() + fieldButton.size();
    final JButton button = new JButton("ADD");
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {

            if (button.getText().equals("ADD")) {
                button.setText("REMOVE");
                addRowBelow();
                frame.pack();
            } else if (button.getText().equals("REMOVE")) {
                button.setText("ADD");

                frame.pack();
            }

        }
    });
    panel.add(button, constraints);
    fieldButton.add(button);
    panel.revalidate(); // redo layout for extra column
}

private void addRowBelow() {
    y++;
    constraints.gridy = y;

    // System.out.println(fields.size());
    for (int x = 0; x < fields.size(); x++) {
        constraints.gridx = x;
        final JTextField field = new JTextField(40);
        field.setEditable(false);
        panel.add(field, constraints);
        constraints.gridx = x + 1;
        final JButton button = new JButton("ADD");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                if (button.getText().equals("ADD")) {
                    button.setText("REMOVE");
                    addRowBelow();
                    frame.pack();
                } else if (button.getText().equals("REMOVE")) {
                    button.setText("ADD");

                    frame.pack();
                }
            }
        });
        panel.add(button, constraints);
    }
}

public void actionPerformed(ActionEvent ae) {
    if ("Add Another TextField and Button".equals(ae.getActionCommand())) {
        addRowBelow();
        frame.pack();
        frame.setLocationRelativeTo(null);
    }
}
}

1 个答案:

答案 0 :(得分:3)

尝试使用GridBagLayout让你变得非常复杂。当您执行此类操作时,嵌套布局方案更容易使用。

请参阅此MCVE:

field listing

我不确定我是否理解您的预期功能100%正确,但我认为它并不像布局那么重要。

我的布局方案如下:

layout scheme

这很好,因为BoxLayout将处理垂直列表而没有太多的喧嚣。而不是必须与GridBagConstraints争论,文本字段和按钮由面板包含在一起。

import javax.swing.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Insets;

public class FieldList implements Runnable, ActionListener {
    public static void main(String... args) {
        SwingUtilities.invokeLater(new FieldList());
    }

    final int maxFields = 2;

    JFrame frame;
    JPanel listing;

    @Override
    public void run() {
        frame = new JFrame("Text Field Listing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel content = new JPanel(new BorderLayout());
        content.add(new JLabel("Input Form", JLabel.CENTER), BorderLayout.NORTH);

        listing = new JPanel();
        listing.setLayout(new BoxLayout(listing, BoxLayout.Y_AXIS));

        content.add(listing, BorderLayout.CENTER);
        frame.setContentPane(content);

        addNewField();

        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    void addNewField() {
        FieldButtonPair field = new FieldButtonPair();
        field.button.addActionListener(this);
        listing.add(field);
        frame.pack();
    }

    void removeLastField() {
        listing.remove(listing.getComponentCount() - 1);
        frame.pack();
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        AddRemoveButton source = (AddRemoveButton)ae.getSource();

        if(source.state == AddRemoveButton.State.ADD) {
            if(listing.getComponentCount() < maxFields) {
                addNewField();
                source.setState(AddRemoveButton.State.REMOVE);
            }
        } else if(source.state == AddRemoveButton.State.REMOVE) {
            removeLastField();
            source.setState(AddRemoveButton.State.ADD);
        }
    }
}

class FieldButtonPair extends JPanel {
    JTextField field;
    AddRemoveButton button;

    FieldButtonPair() {
        super(new BorderLayout());
        field = new JTextField();
        add(field, BorderLayout.CENTER);
        button = new AddRemoveButton();
        add(button, BorderLayout.EAST);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension pref = super.getPreferredSize();
        pref.width = Math.max(480, pref.width);
        return pref;
    }
}

class AddRemoveButton extends JButton {
    enum State { ADD, REMOVE }

    State state = State.ADD;

    AddRemoveButton() {
        setText(state.name());
    }

    void setState(State state) {
        setText(state.name());
        this.state = state;
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension pref = super.getPreferredSize();

        Font f = getFont();
        FontMetrics fm = getFontMetrics(f);
        int w = fm.stringWidth(State.REMOVE.name());
        Insets ins = getInsets();

        pref.width = (ins.left + w + ins.right);
        return pref;
    }
}