JTabbedPane中的选项卡不反映按下按钮时的更改

时间:2012-06-13 01:21:18

标签: java swing user-interface jtabbedpane

在我的GUI选项卡中,允许用户编辑员工的姓名。该名称也用作选项卡的标签,因此当确认更改时,应更新选项卡以反映此更改,并将新数据写入数据文件。

员工存储在班级HashMap的{​​{1}}中。通过迭代Employees员工的名称来填充选项卡,这些名称来自调用方法ArrayList<String>。在GUI中,用户可以键入新名称,然后按更改名称按钮。按钮的Employees.getNames()调用方法ActionListener,该方法用changeName()中的新名称替换旧名称并更新数据文件。

这在用户第一次想要更改员工姓名时正常工作,但后续更改会产生错误。包含HashMap的{​​{1}}(请参阅下面的JPanel)似乎未更新参数JTextFields。此参数是员工的当前名称,而新名称来自getEmployeeInfoPanel()

以下是说明此问题的示例。基本上,步骤是:

name

此特定屏幕的层次结构为:

JTextField

以下是GUI的相关代码:

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.

以下是更改HashMap的Employees类的代码:

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; } } 会这样做。

(前)

enter image description here

(按下按钮后)

enter image description here

最后,按下更改名称按钮两次的输出产生,显示名称已在ArrayList中更改:

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.");
    }
}

1 个答案:

答案 0 :(得分: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();
            }
        });
    }
}