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 を変更するクラス Employees のコードは次のとおりです。
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.");
}
}
ここに例があります。最初のスクリーン ショットは、プログラムが開始されたときのものです。従業員の名前が適切なタブに取り込まれます。2 番目のスクリーンショットは、従業員の名前を変更しようとした後のものです。ご覧のとおり、タブのラベルは変更されていvalidate()
ません。
(前)
(ボタンを押した後)
最後に、名前の変更ボタンを 2 回押すと、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.