java - 如何使用 'ADD'按钮重复添加JPanel?如何在ActionListener()中调用JPanel?

标签 java swing jpanel call

我想使用“添加”按钮重复就业历史 JPanel(内容为灰色),并使用“删除”按钮将其删除。 This is the GUI 我还想知道如何临时存储文本字段的值。数组会有帮助吗?

这是代码

    JLabel lblEmploymentHistory = new JLabel("Employment History:");
    lblEmploymentHistory.setBounds(46, 145, 128, 14);
    frame.getContentPane().add(lblEmploymentHistory);

    JPanel panelemp = new JPanel();
    panelemp.setBounds(46, 170, 435, 63);
    panelemp.setBackground(Color.GRAY);
    frame.getContentPane().add(panelemp);

    JLabel lblRoleHeld = new JLabel("Role Held:");
    panelemp.add(lblRoleHeld);

    txtRole = new JTextField();
    txtRole.setText("role");
    panelemp.add(txtRole);
    txtRole.setColumns(10);

    JLabel lblDuration = new JLabel("Duration:");
    panelemp.add(lblDuration);

    txtDuration = new JTextField();
    txtDuration.setText("duration");
    panelemp.add(txtDuration);
    txtDuration.setColumns(10);

    JLabel lblEmployer = new JLabel("Employer:");
    panelemp.add(lblEmployer);

    txtEmployer = new JTextField();
    txtEmployer.setText("employer");
    panelemp.add(txtEmployer);
    txtEmployer.setColumns(10);

    JButton Addnewemphis = new JButton("Add");
    Addnewemphis.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

        }
    });
    panelemp.add(Addnewemphis);

    JButton btnRemove = new JButton("Remove");
    btnRemove.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {

        }
    });
    panelemp.add(btnRemove);

最佳答案

先退一步。您需要学习和理解一个关键概念 - 职责分离。

您需要将功能分离并隔离到单独的类中,这将使快速、简单地开发重复功能变得更加容易。

您还应该专注于将“数据”的管理与“用户界面”分开,以便用户界面代表您的数据并用于(如果适用)更新它。

根据您当前的设计,无法“选择”员工历史记录面板,因此“通用”删除操作毫无意义 - 您会删除哪一个?相反,该操作实际上属于员工历史记录面板本身,但添加和删除这些组件的责任完全由单独的 Controller 负责。

让我们从一个基本概念开始,您首先需要一些数据......

public class EmployeeHistory {

    private String role;
    private String duration;
    private String employer;

    public EmployeeHistory() {
    }

    public EmployeeHistory(String role, String duration, String employer) {
        this.role = role;
        this.duration = duration;
        this.employer = employer;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getDuration() {
        return duration;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

    public String getEmployer() {
        return employer;
    }

    public void setEmployer(String employer) {
        this.employer = employer;
    }

}

就我个人而言,我更喜欢一个界面,可能是“只读”和“读写”访问的界面,但为了简洁起见,我们将坚持使用这一点。

接下来,我们需要某种方式来显示它......

public class HistoryPane extends JPanel {

    private final JTextField txtRole;
    private final JTextField txtDuration;
    private final JTextField txtEmployer;

    private final JButton removeButton;

    private EmployeeHistory history;

    public HistoryPane(EmployeeHistory history) {
        // This is what you should use when you want to populate
        // the view or properties of the UI are changed
        this.history = history;
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;

        JLabel lblRoleHeld = new JLabel("Role Held:");
        add(lblRoleHeld, gbc);

        gbc.gridx++;
        txtRole = new JTextField();
        txtRole.setText("role");
        add(txtRole, gbc);
        txtRole.setColumns(10);

        gbc.gridx = 0;
        gbc.gridy++;
        JLabel lblDuration = new JLabel("Duration:");
        add(lblDuration, gbc);

        gbc.gridx++;
        txtDuration = new JTextField();
        txtDuration.setText("duration");
        add(txtDuration, gbc);
        txtDuration.setColumns(10);

        gbc.gridx = 0;
        gbc.gridy++;
        JLabel lblEmployer = new JLabel("Employer:");
        add(lblEmployer, gbc);

        gbc.gridx++;
        txtEmployer = new JTextField();
        txtEmployer.setText("employer");
        add(txtEmployer, gbc);
        txtEmployer.setColumns(10);

        gbc.gridx = 0;
        gbc.gridy++;
        gbc.gridwidth = GridBagConstraints.REMAINDER;

        removeButton = new JButton("Remove");
        add(removeButton, gbc);
    }

    public EmployeeHistory getHistory() {
        return history;
    }

    public void addActionListener(ActionListener listener) {
        removeButton.addActionListener(listener);
    }

    public void removeActionListener(ActionListener listener) {
        removeButton.removeActionListener(listener);
    }

}

nb:我没有费心用数据填充 View ,我相信你可以把它说出来

这里需要注意的是,removeButton 实际上并没有做任何事情,责任被委托(delegate)给其他方

好的,我们可以删除,但是如何添加呢?好吧,你需要另一个组件......

public class ActionPane extends JPanel {

    private JButton btn;

    public ActionPane() {
        setLayout(new GridBagLayout());
        btn = new JButton("Add");
        add(btn);
    }

    public void addActionListener(ActionListener listener) {
        btn.addActionListener(listener);
    }

    public void removeActionListener(ActionListener listener) {
        btn.removeActionListener(listener);
    }

}

再说一遍,这实际上并没有做任何事情,它只是将责任委托(delegate)给其他人。

nb:这是一个基本示例,同样,您可以传入某种充当委托(delegate)的 Controller ,但结果基本相同

好吧,但是这一切是如何运作的呢?好吧,您只需要将所有功能整合在一起......

所以这是添加和删除功能的可能实现

ActionPane actionPane = new ActionPane();
actionPane.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // Layout constraints
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // The actually history data
        EmployeeHistory history = new EmployeeHistory();
        // This is a model to manage the individual histories, making
        // it easier to manage
        histories.add(history);
        // The history view...
        HistoryPane pane = new HistoryPane(history);
        // The remove action...
        pane.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Remove the action to improve the chances of been
                // garbage collected
                pane.removeActionListener(this);
                // Remove the history from our model
                histories.remove(pane.getHistory());
                // Remove the view
                contentPane.remove(pane);
                contentPane.revalidate();
                contentPane.repaint();
            }
        });
        // Add the view (this is a little trick ;))
        contentPane.add(pane, gbc, contentPane.getComponentCount() - 1);
        contentPane.revalidate();
        contentPane.repaint();
    }
});

可运行示例

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JPanel contentPane;
        private List<EmployeeHistory> histories;

        public TestPane() {
            histories = new ArrayList<>(25);
            setLayout(new BorderLayout());

            contentPane = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.weighty = 1;
            contentPane.add(new JPanel(), gbc);

            JScrollPane scrollPane = new JScrollPane(contentPane);
            add(scrollPane);

            ActionPane actionPane = new ActionPane();
            actionPane.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
                    gbc.weightx = 1;
                    gbc.fill = GridBagConstraints.HORIZONTAL;

                    EmployeeHistory history = new EmployeeHistory();
                    histories.add(history);
                    HistoryPane pane = new HistoryPane(history);
                    pane.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            pane.removeActionListener(this);
                            histories.remove(pane.getHistory());
                            contentPane.remove(pane);
                            contentPane.revalidate();
                            contentPane.repaint();
                        }
                    });
                    contentPane.add(pane, gbc, contentPane.getComponentCount() - 1);
                    contentPane.revalidate();
                    contentPane.repaint();
                }
            });
            add(actionPane, BorderLayout.SOUTH);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

    }

    public class ActionPane extends JPanel {

        private JButton btn;

        public ActionPane() {
            setLayout(new GridBagLayout());
            btn = new JButton("Add");
            add(btn);
        }

        public void addActionListener(ActionListener listener) {
            btn.addActionListener(listener);
        }

        public void removeActionListener(ActionListener listener) {
            btn.removeActionListener(listener);
        }

    }

    public class EmployeeHistory {

        private String role;
        private String duration;
        private String employer;

        public EmployeeHistory() {
        }

        public EmployeeHistory(String role, String duration, String employer) {
            this.role = role;
            this.duration = duration;
            this.employer = employer;
        }

        public String getRole() {
            return role;
        }

        public void setRole(String role) {
            this.role = role;
        }

        public String getDuration() {
            return duration;
        }

        public void setDuration(String duration) {
            this.duration = duration;
        }

        public String getEmployer() {
            return employer;
        }

        public void setEmployer(String employer) {
            this.employer = employer;
        }

    }

    public class HistoryPane extends JPanel {

        private final JTextField txtRole;
        private final JTextField txtDuration;
        private final JTextField txtEmployer;

        private final JButton removeButton;

        private EmployeeHistory history;

        public HistoryPane(EmployeeHistory history) {
            // This is what you should use when you want to populate
            // the view or properties of the UI are changed
            this.history = history;
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;

            JLabel lblRoleHeld = new JLabel("Role Held:");
            add(lblRoleHeld, gbc);

            gbc.gridx++;
            txtRole = new JTextField();
            txtRole.setText("role");
            add(txtRole, gbc);
            txtRole.setColumns(10);

            gbc.gridx = 0;
            gbc.gridy++;
            JLabel lblDuration = new JLabel("Duration:");
            add(lblDuration, gbc);

            gbc.gridx++;
            txtDuration = new JTextField();
            txtDuration.setText("duration");
            add(txtDuration, gbc);
            txtDuration.setColumns(10);

            gbc.gridx = 0;
            gbc.gridy++;
            JLabel lblEmployer = new JLabel("Employer:");
            add(lblEmployer, gbc);

            gbc.gridx++;
            txtEmployer = new JTextField();
            txtEmployer.setText("employer");
            add(txtEmployer, gbc);
            txtEmployer.setColumns(10);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            removeButton = new JButton("Remove");
            add(removeButton, gbc);
        }

        public EmployeeHistory getHistory() {
            return history;
        }

        public void addActionListener(ActionListener listener) {
            removeButton.addActionListener(listener);
        }

        public void removeActionListener(ActionListener listener) {
            removeButton.removeActionListener(listener);
        }

    }

}

现在,说了这么多,去读一下 How to Use TablesHow to Use Lists

Will an array be helpful?

不,不是真的。这将限制您可以显示的历史元素的数量。相反,我会使用 ArrayList 来管理历史对象的实例,如上面所示

关于java - 如何使用 'ADD'按钮重复添加JPanel?如何在ActionListener()中调用JPanel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52143526/

相关文章:

java - 在 BST 中插入元素时出现 NullPointerException

java - 在 Java 中从二维数组构建图像

java - JNI 文档中 "Unicode string"是什么意思?

java - NetworkInterface 的 getNetworkInterfaces() 到 JComboBox

java - 如何禁用 JPanel 中的所有组件

java - Swing JPanel 切换超出范围

java - HSQLDB 中可以有 CURSOR 类型的 OUT 参数吗?

java - 在jtable中排序整数

java - 如何去除打印页面的边距

java - Canvas 上的透明 JPanel (VLCJ)