2

GUI のタブ内で、ユーザーは従業員の名前を編集できます。名前はタブのラベルとしても機能するため、変更が確認されると、この変更を反映するようにタブを更新する必要があり、新しいデータがデータ ファイルに書き込まれます。

HashMap従業員はクラス内の に格納されEmployeesます。ArrayList<String>メソッドを呼び出して取得した従業員の名前を反復処理することで、タブに値が入力されますEmployees.getNames()。GUI から、ユーザーは新しい名前を入力してから、名前の変更ボタンを押すことができます。ボタンActionListenerは メソッド を呼び出します。このメソッドchangeName()は、 内の古い名前を新しい名前に置き換え、HashMapデータ ファイルを更新します。

これは、ユーザーが最初に従業員の名前を変更したい場合には正しく機能しますが、その後の変更ではエラーが発生します。(下記参照)JPanelを含む がパラメータを更新していないようです。このパラメータは従業員の現在の名前ですが、新しい名前は から取得されます。JTextFieldsgetEmployeeInfoPanel()nameJTextField

この問題を説明する例を以下に示します。基本的に、手順は次のとおりです。

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.
4

1 に答える 1

4

setTitleAt()メソッドを探しているかもしれません。

補遺: 比較のために、複数の編集を許可するsscceを次に示します。

タブ編集

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();
            }
        });
    }
}
于 2012-06-13T01:30:54.370 に答える