JAVA jframe.remove(面板)没有按预期工作
JAVA jframe.remove(panel) doesn't work as expected
我有一个带有两个面板的 Jframe,我正在尝试使用 jmenu 项更改 panels/views。
第一个面板将数据添加到数据库。然后,用户可以通过单击 JMenuBarItem 切换到视图面板。
第二个面板从数据库中获取数据并将结果显示在 JTable 中。
一切正常,但是当我来回切换到第二个面板时,它会添加另一个面板而不是删除它 it/replacing。请参阅下面的链接图片以更好地理解
第一个面板
第二个面板
来回切换后的第二个面板
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();
}
}
您犯的错误是每次打开视图面板时都创建了一个新的 JTable。您不仅可以创建一个新的,您还可以将它添加到您的视图 JPanel。这就是为什么你会出现奇怪的行为。
此代码段解决了您的问题。我刚刚将 removeAll()
方法调用添加到 add-JPanel ActionListener。打开 add-JPanel 时,旧的 JTable 将从 view-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 去哪里,但你可以 删除 table 的内容,并在你再次打开 view-JPanel 后立即重新填充它们.
另一种解决方案是专门删除 JTable(但在这种情况下,您可能需要将它作为一个字段,因为您在您无法从 add.addActionListener
-Block)
引用的区块
第三个解决方案是添加一个 布尔标志,检查 table 是否已加载,如果没有加载则只创建一个新的 JTable .
我有一个带有两个面板的 Jframe,我正在尝试使用 jmenu 项更改 panels/views。
第一个面板将数据添加到数据库。然后,用户可以通过单击 JMenuBarItem 切换到视图面板。
第二个面板从数据库中获取数据并将结果显示在 JTable 中。
一切正常,但是当我来回切换到第二个面板时,它会添加另一个面板而不是删除它 it/replacing。请参阅下面的链接图片以更好地理解
第一个面板
第二个面板
来回切换后的第二个面板
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();
}
}
您犯的错误是每次打开视图面板时都创建了一个新的 JTable。您不仅可以创建一个新的,您还可以将它添加到您的视图 JPanel。这就是为什么你会出现奇怪的行为。
此代码段解决了您的问题。我刚刚将 removeAll()
方法调用添加到 add-JPanel ActionListener。打开 add-JPanel 时,旧的 JTable 将从 view-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 去哪里,但你可以 删除 table 的内容,并在你再次打开 view-JPanel 后立即重新填充它们.
另一种解决方案是专门删除 JTable(但在这种情况下,您可能需要将它作为一个字段,因为您在您无法从 add.addActionListener
-Block)
第三个解决方案是添加一个 布尔标志,检查 table 是否已加载,如果没有加载则只创建一个新的 JTable .