Вкладка в JTabbedPane не отражает изменения при нажатии кнопки

java swing user-interface jtabbedpane

1508 просмотра

1 ответ

На вкладке моего графического интерфейса пользователю разрешено редактировать имя сотрудника. Имя также служит меткой вкладки, поэтому, когда изменение подтверждается, вкладка должна быть обновлена, чтобы отразить это изменение, и новые данные записываются в файл данных.

Сотрудники хранятся HashMapв классе Employees. Вкладки заполняются путем перебора ArrayList<String>имен сотрудников, получаемых при вызове метода Employees.getNames(). Из графического интерфейса пользователь может ввести новое имя и затем нажать кнопку изменения имени. Кнопка 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)
   |
    -- .....

А вот соответствующий код из графического интерфейса:

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;
    }
}

и вот код из класса Employees, который изменяет 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.
Автор: A D Источник Размещён: 12.11.2019 09:40

Ответы (1)


4 плюса

Решение

Возможно, вы ищете setTitleAt()метод.

Приложение: Для сравнения, вот sscce, который позволяет несколько изменений.

TabEdit

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

/**
 * @see http://stackoverflow.com/a/11007109/230513
 */
public class TabEdit extends JPanel {

    private static final int MAX = 5;
    private static final String NAME = "Tab ";
    private final JTabbedPane pane = new JTabbedPane();

    public TabEdit() {
        for (int i = 0; i < MAX; i++) {
            pane.add(NAME + String.valueOf(i), new TabContent(i));
        }
        this.add(pane);
    }

    private class TabContent extends JPanel {

        private TabContent(final int i) {
            final JTextField jtf = new JTextField(
                "Please edit the name of " + NAME + String.valueOf(i));
            this.add(jtf);
            jtf.addActionListener(new AbstractAction() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    pane.setTitleAt(i, jtf.getText());
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(320, 120);
        }
    }

    private void display() {
        JFrame f = new JFrame("TabEdit");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TabEdit().display();
            }
        });
    }
}
Автор: trashgod Размещён: 13.06.2012 01:30
Вопросы из категории :
32x32