在我的 GUI 的选项卡中,允许用户编辑员工的姓名。该名称还用作选项卡的标签,因此当确认更改时,应更新选项卡以反映此更改,并将新数据写入数据文件。
员工存储在一个HashMap
类中Employees
。这些选项卡是通过迭代一个ArrayList<String>
员工的名字来填充的,这是通过调用方法获得的Employees.getNames()
。从 GUI 中,用户可以输入新名称,然后按更改名称按钮。按钮ActionListener
调用方法changeName()
,该方法将旧名称替换为新名称HashMap
并更新数据文件。
这在用户第一次想要更改员工姓名时可以正常工作,但随后的更改会产生错误。似乎JPanel
包含JTextFields
(见getEmployeeInfoPanel()
下文)的 没有更新参数name
。此参数是员工的当前姓名,而新姓名是从JTextField
.
下面是一个例子来说明这个问题。基本上,这些步骤是:
1. old name = Mary is provided when the program starts
2. User changes name in JTextField, so oldName = Mary and newName = Mary S.
3. At this point, oldName should update to Mary S. as it is the new key.
However, oldName remains as Mary so the HashMap cannot be updated again.
这个特定屏幕的层次结构是:
JFrame (entire application)
|
-- JPanel EmployeesPanel (this screen)
| |
| -- JPanel (for custom menu bar)
| |
| -- JTabbedPane (one tab for each employee)
| |
| -- JPanel (contains JLabels, JTextField, etc for this employee)
|
-- .....
这是来自 GUI 的相关代码:
public class EmployeesPanel {
private JTabbedPane pane;
private Employees employees;
...
public EmployeesPanel(JPanel panel, Container cards) {
...
pane = new JTabbedPane();
getEmployees();
}
private void getEmployees() {
...
employees = new Employees(properties, EMPLOYEES_TXT);
//ArrayList of all employees' names
names = employees.getNames();
for(String name : names) {
pane.addTab(name, getEmployeeInfoPanel(name));
}
pane.addTab("NEW EMPLOYEE", addEmployeePanel());
}
public JPanel addEmployeePanel() {
...
}
private JPanel getEmployeeInfoPanel(final String name) throws EmployeeException {
JPanel infoPanel = new JPanel();
infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.PAGE_AXIS));
JLabel nameLabel = new JLabel("Employee name");
JLabel wageLabel = new JLabel("Employee wage");
final JTextField nameField = new JTextField(name, 30);
final JTextField wageField = new JTextField(employees.getWage(name).toString(), 30);
JButton changeNameButton = new JButton("CHANGE NAME");
JButton changeWageButton = new JButton("CHANGE WAGE");
changeNameButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
String newName = nameField.getText();
employees.changeName(name, newName);
panel.validate();
} catch (EmployeeException e) {
// TODO create popup warning
}
}
});
...
return infoPanel;
}
}
这里是修改 HashMap 的雇员类的代码:
public void changeName(String oldName, String newName) throws EmployeeException {
System.out.println("old name = " + oldName + ", new name = " + newName);
if(employees.containsKey(oldName)) {
BigDecimal wage = employees.get(oldName);
employees.remove(oldName);
employees.put(newName, wage);
names.remove(oldName);
names.add(newName);
prop.remove(oldName);
prop.setProperty(newName, wage.toString());
saveProperties();
System.out.println(names);
} else {
throw new EmployeeException("Could not change name because employee does not exist.");
}
}
这是一个例子。第一个屏幕截图是从程序启动时开始的;员工姓名被填充到相应的选项卡中。第二个屏幕截图是在尝试更改员工姓名之后。正如你所看到的,标签的标签没有改变,我假设调用validate()
会这样做。
(前)
(按下按钮后)
最后,按两次更改名称按钮会产生输出,显示名称已在 ArrayList 中更改:
old name = Mary, new name = Mary S.
[Jane, Bob, Sue, Mary S.]
old name = Mary, new name = Mary S.
653647 [AWT-EventQueue-0] ERROR employees.EmployeeException - Could not change name because employee does not exist.