首页 > 解决方案 > JAVA jframe.remove(panel) 无法按预期工作

问题描述

我有一个带有两个面板的 Jframe,我正在尝试使用 jmenu 项更改面板/视图。

第一个面板将数据添加到数据库。然后,用户可以通过单击 JMenuBarItem 切换到视图面板。

第二个面板从数据库中获取数据并在 JTable 中显示结果。

一切正常,但是当我来回切换到第二个面板时,它会添加另一个面板,而不是删除/替换它。请参阅下面的链接图片以更好地理解

第一面板

第一面板

第二面板

第二面板

来回切换后的第二个面板

来回切换后的第二个面板

package employeerecords3;

import java.awt.*;
import java.awt.event.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import javax.swing.*;


public class EmployeeRecords3 extends JFrame {

    JLabel empnolb, empnamelb, empdptlb, basicsallb, hseallowancelb;
    JTextField empnotf, empnametf, empdpttf, basicsaltf, hseallowancetf;
    JButton submitbtn, cancelbtn;
    String host = "jdbc:mysql://localhost:3306/employee";
    String username = "root";
    String password = "";

    EmployeeRecords3() {
        setTitle("Employee Records");

        final JPanel addpanel = new JPanel();
        final JPanel viewpanel = new JPanel();
        setTitle("Employee Records");

        JMenuBar menubar = new JMenuBar();
        setJMenuBar(menubar);
        JMenu file = new JMenu("File");
        menubar.add(file);
        JMenuItem add = new JMenuItem("Add Employee");
        JMenuItem view = new JMenuItem("View Employees");
        file.add(add);
        file.add(view);

        add.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                if (viewpanel.isShowing()) {
                    remove(viewpanel);
                    add(addpanel);
                }

                revalidate();
                repaint();
            }
        });
        view.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                java.util.List<String[]> datalist = new ArrayList<>();

                String[] columnNames = {"Emp ID", "Emp Name", "Department", "Basic Pay", "House Allowance", "Payee", "NHIF", "NSSF", "Pension", "NetPay"};
                try {
                    String query = "SELECT * FROM payroll";
                    Class.forName("com.mysql.jdbc.Driver");
                    Connection con = DriverManager.getConnection(host, username, password);
                    Statement st = con.prepareStatement(query);
                    ResultSet rs = st.executeQuery(query);
                    while (rs.next()) {
                        String[] results = {rs.getString(1), rs.getString(2), rs.getString(3), Double.toString(rs.getDouble(4)), Double.toString(rs.getDouble(5)), Double.toString(rs.getDouble(6)), Double.toString(rs.getDouble(7)), Double.toString(rs.getDouble(8)), Double.toString(rs.getDouble(9)), Double.toString(rs.getDouble(10))};
                        datalist.add(results);
                    }
                    con.close();
                    String[][] data = new String[datalist.size()][];
                    data = datalist.toArray(data);
                    JTable table = new JTable(data, columnNames);

                    JScrollPane sp = new JScrollPane(table);
                    viewpanel.add(sp);

                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                if (addpanel.isShowing()) {
                    remove(addpanel);
                    add(viewpanel);
                } else if (viewpanel.isShowing()) {
                    remove(viewpanel);
                    add(viewpanel);
                }

                revalidate();
                repaint();
            }
        });

        empnolb = new JLabel("Emp No");
        empnamelb = new JLabel("Name");
        empdptlb = new JLabel("Department");
        basicsallb = new JLabel("Basic Pay");
        hseallowancelb = new JLabel("House Allowance");

        empnotf = new JTextField();
        empnametf = new JTextField();
        empdpttf = new JTextField();
        basicsaltf = new JTextField();
        hseallowancetf = new JTextField();

        submitbtn = new JButton("Submit");
        cancelbtn = new JButton("Cancel");

        Submit submithandler = new Submit();
        submitbtn.addActionListener(submithandler);

        Cancel cancelhandler = new Cancel();
        cancelbtn.addActionListener(cancelhandler);

        addpanel.add(empnolb);
        addpanel.add(empnotf);

        addpanel.add(empnamelb);
        addpanel.add(empnametf);

        addpanel.add(empdptlb);
        addpanel.add(empdpttf);

        addpanel.add(basicsallb);
        addpanel.add(basicsaltf);

        addpanel.add(hseallowancelb);
        addpanel.add(hseallowancetf);

        addpanel.add(submitbtn);
        addpanel.add(cancelbtn);

        addpanel.setLayout(new GridLayout(6, 2));
        viewpanel.setLayout(new GridLayout(1, 1));
        add(addpanel);
        setSize(300, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setVisible(true);

    }

    private class Submit implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String empNo, empName, department;
            double grossPay, basicPay, hseAllowance, payee, nhif, nssf, pension, netPay;

            empNo = empnotf.getText();
            empName = empnametf.getText();
            department = empdpttf.getText();
            basicPay = Double.parseDouble(basicsaltf.getText());
            hseAllowance = Double.parseDouble(hseallowancetf.getText());

            grossPay = basicPay + hseAllowance;
            payee = 0.3 * grossPay;
            if (grossPay > 100000) {
                nhif = 1200;
            } else {
                nhif = 320;
            }
            nssf = 200;
            pension = 0.05 * basicPay;
            netPay = grossPay - (payee - nhif - nssf - pension);

            String query = "INSERT INTO payroll(EmpID,EmpName,Department,BasicPay,HouseAllowance,Payee,NHIF,NSSF,Pension,NetPay) VALUES('" + empNo + "','" + empName + "','" + department + "','" + basicPay + "','" + hseAllowance + "','" + payee + "','" + nhif + "','" + nssf + "','" + pension + "','" + netPay + "')";

            try {

                Class.forName("com.mysql.jdbc.Driver");
                Connection con = DriverManager.getConnection(host, username, password);
                Statement st = con.prepareStatement(query);

                int count = st.executeUpdate(query);
                boolean action = (count > 0);
                if (action) {
                    empnotf.setText(null);
                    empnametf.setText(null);
                    empdpttf.setText(null);
                    basicsaltf.setText(null);
                    hseallowancetf.setText(null);
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            }

        }
    }

    private class Cancel implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }
    }

    public static void main(String[] args) {

        EmployeeRecords3 er = new EmployeeRecords3();
    }

}

标签: javajpanel

解决方案


您犯的错误是每次打开视图面板时都会创建一个新的 JTable 。您不仅创建了一个新的,还将它添加到您的 view-JPanel中。这就是为什么你会得到奇怪的行为。

此代码段解决了您的问题。我刚刚将removeAll()方法调用添加到 add-JPanel ActionListener。当 add-JPanel 打开时,旧的 JTable 将从视图 JPanel 中删除。我不得不注释掉你的数据库交互。

    // ...
    // ...
    // ...
    add.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            if (viewpanel.isShowing())
            {
                remove(viewpanel);
                /*
                 * I basically just added this one line.
                 * Since you want to make a fresh query after
                 * you come back to the viewpanel, we can delete
                 * all the elements (which is only the JTable).
                 */
                viewpanel.removeAll();
                add(addpanel);
            }

            revalidate();
            repaint();
        }
    });

    view.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            java.util.List<String[]> datalist = new ArrayList<>();

            String[] columnNames = {"Emp ID", "Emp Name", "Department",
                    "Basic Pay", "House Allowance", "Payee", "NHIF", "NSSF",
                    "Pension", "NetPay"};
            try
            {
                //                    String query = "SELECT * FROM payroll";
                //                    Class.forName("com.mysql.jdbc.Driver");
                //                    Connection con = DriverManager.getConnection(host, username,
                //                            password);
                //                    Statement st = con.prepareStatement(query);
                //                    ResultSet rs = st.executeQuery(query);
                String[] results = {"a", "b", "c", "d", "e", "f", "g", "h",
                        "i", "j"};
                datalist.add(results);
                //                    con.close();
                String[][] data = new String[datalist.size()][];
                data = datalist.toArray(data);
                JTable table = new JTable(data, columnNames);

                JScrollPane sp = new JScrollPane(table);
                viewpanel.add(sp);

            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
            if (addpanel.isShowing())
            {
                remove(addpanel);
                add(viewpanel);
            }
            else if (viewpanel.isShowing())
            {
                remove(viewpanel);
                add(viewpanel);
            }

            revalidate();
            repaint();
        }
    });
    // ...
    // ...
    // ...

上面的解决方案当然不是唯一的。我不知道你想用这个 UI 去哪里,但你可以删除表格的内容并在再次打开 view-JPanel 时重新填充它们

另一种解决方案是专门删除 JTable(但在这种情况下,您可能需要将其作为字段,因为您在无法从add.addActionListener-Block 引用的块中创建表)

第三种解决方案是添加一个布尔标志,它检查表是否已加载,如果没有,则仅创建一个新的 JTable


推荐阅读