2012-06-13 2 views
2

에 변경 사항이 반영되지 않으며, 사용자는 직원의 이름을 편집 할 수 있습니다. 이름이 탭의 레이블이기도하므로 변경이 확인되면 탭이이 변경 사항을 반영하도록 업데이트되고 새 데이터가 데이터 파일에 기록됩니다.탭 내 GUI의 탭에서 버튼을 눌러

직원은 Employees 클래스의 HashMap에 저장됩니다. 탭은 직원 이름의 ArrayList<String>을 반복하여 채우고, 이는 Employees.getNames() 메서드를 호출하여 가져옵니다. GUI에서 사용자는 새 이름을 입력 한 다음 이름 변경 버튼을 누를 수 있습니다. 단추 ActionListenerchangeName() 메서드를 호출합니다.이 메서드는 이전 이름을 HashMap의 새 이름으로 바꾸고 데이터 파일을 업데이트합니다.

이 올바르게 사용자가 직원의 이름을 변경하고자 처음 작동하지만, 이후의 변화는 오류를 얻을 수 있습니다. JTextFields (아래 getEmployeeInfoPanel() 참조)이 포함 된 JPanel은 매개 변수 name을 업데이트하지 않는 것으로 보입니다. 이 매개 변수는 직원의 현재 이름이고 JTextField에서 새 이름을 가져옵니다. 이 문제를 설명하기

예는 아래와 같다. 본질적으로, 단계는 다음과 같습니다

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에서 관련 코드입니다 :

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. 

이 특정 화면의 계층 구조는

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

여기에 코드입니다

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."); 
    } 
} 
: HashMap의 변경 클래스 종업원 수에서

다음은 예제입니다. 첫 번째 스크린 샷은 프로그램이 시작된 시점부터입니다. 직원 이름이 해당 탭에 채워집니다. 두 번째 스크린 샷은 직원의 이름을 변경하려고 시도한 후입니다. 보시다시피, 탭의 레이블은 변경되지 않았으므로 validate()이라는 호출을 사용한다고 가정했습니다.

enter image description here

그리고

enter image description here

(버튼을 누른 후) (전) 마지막 두번 이름 변경 버튼을 누르면 이름되었음을 나타내는 생산 출력

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. 
: ArrayList의 변경
+0

나는 오류가 발생한 코드가 표시되지 않습니다. –

+0

이름 변경 버튼을 누르면 오류가 발생합니다.버튼의 ActionListener는''changeName()''메서드를 호출합니다.이 메서드는 직원의 이전 이름을 새 이름으로 바꿉니다. 처음에는 이름을 바꿀 수 있지만 탭을 업데이트하지는 않습니다. 이후의 변경으로 인해 오류가 발생합니다. –

+0

JTabbedPane의 제목을 @trashgod에서 권장하는대로 설정했지만 여전히 문제가있는 경우 질문과 코드가 문제를 추측하기에 충분하지 않다고 생각됩니다. –

답변

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+. –

관련 문제