2012-06-13 52 views
2

在我的GUI的選項卡中,允許用戶編輯員工的姓名。該名稱還可用作選項卡的標籤,因此在確認更改時應更新選項卡以反映此更改,並將新數據寫入數據文件。JTabbedPane中的選項卡不反映按鈕上的更改

員工存儲在類Employees中的HashMap中。通過迭代通過調用方法Employees.getNames()獲得的員工姓名的ArrayList<String>填充選項卡。在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; 
    } 
} 

這裏是代碼來自班級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()會做。

(之前)

enter image description here

(後按下按鈕)

enter image description here

最後,在按下改變名稱按鈕兩次產生,顯示出名字已輸出在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. 
+0

我沒有看到,其中發生錯誤的代碼。 –

+0

按下更改名稱按鈕時發生錯誤。該按鈕的ActionListener調用方法''changeName()'',它用新名稱替換員工的舊名稱。第一次成功替換名稱但不更新選項卡,並且任何後續更改都會導致錯誤。 –

+0

如果您正在按照@trashgod的建議設置JTabbedPane的標題,但仍然存在問題,那麼我擔心您的問題和代碼不會顯示出足以猜測問題的內容。 –

回答

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(); 
      } 
     }); 
    } 
} 
+0

感謝您的回覆。這解決了我在選項卡標題中遇到的問題,但我仍無法多次更改員工姓名。 –

+0

我已經詳細闡述過了。 – trashgod

+0

@AD:同樣,我建議您接受這個答案,然後在一個新線程中詢問您的第二個問題。 1+。 –

相關問題