Tabulação no JTabbedPane não reflete as alterações no botão pressionado
Dentro de uma guia da minha GUI, o usuário tem permissão para editar o nome de um funcionário. O nome também serve como rótulo da guia, portanto, quando a alteração é confirmada, a guia deve ser atualizada para refletir essa alteração e os novos dados são gravados em um arquivo de dados.
Os funcionários são armazenados em umHashMap
na aulaEmployees
. As guias são preenchidas por uma iteração por meio deArrayList<String>
dos nomes dos funcionários, que é obtido ao chamar o métodoEmployees.getNames()
. Na GUI, o usuário pode digitar um novo nome e pressionar o botão de mudança de nome. Os botõesActionListener
chama o métodochangeName()
, que substitui o nome antigo pelo novo nome noHashMap
e atualiza o arquivo de dados.
Isso funciona corretamente na primeira vez que um usuário deseja alterar o nome do funcionário, mas as alterações subsequentes geram um erro. Parece que oJPanel
que contém oJTextFields
(VejogetEmployeeInfoPanel()
abaixo) não está atualizando o parâmetroname
. Este parâmetro é o nome atual do funcionário, enquanto o novo nome é obtido doJTextField
.
Um exemplo para ilustrar esse problema está abaixo. Essencialmente, os passos são:
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.
A hierarquia desta tela em particular é:
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)
|
-- .....
E aqui está o código relevante da 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;
}
}
e aqui está o código da classe Funcionários que altera o 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.");
}
}
Aqui está um exemplo. A primeira captura de tela é de quando o programa é iniciado; os nomes dos funcionários são preenchidos nas guias apropriadas. A segunda captura de tela é depois de tentar alterar o nome do funcionário. Como você pode ver, o rótulo da guia não mudou, e eu assumi a chamada paravalidate()
faria.
(Antes)
(Depois de pressionar o botão)
E, finalmente, a saída que pressiona o botão do nome da alteração produz duas vezes, mostrando que o nome foi alterado na 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.