001package edu.pdx.cs410J.grader.gradebook.ui;
002
003import edu.pdx.cs410J.ParserException;
004import edu.pdx.cs410J.grader.gradebook.*;
005
006import javax.swing.*;
007import java.awt.*;
008import java.awt.event.ActionEvent;
009import java.awt.event.ActionListener;
010import java.awt.event.WindowAdapter;
011import java.awt.event.WindowEvent;
012import java.io.FileNotFoundException;
013import java.io.IOException;
014import java.util.Arrays;
015import java.util.Vector;
016import java.util.function.Supplier;
017
018/**
019 * This panel displays a <code>Student</code>
020 */
021@SuppressWarnings("serial")
022public class StudentPanel extends JPanel {
023
024  private Student student;
025  private NotesPanel notes;
026
027  // GUI components we care about
028  private JTextField idField;
029  private JTextField firstNameField;
030  private JTextField lastNameField;
031  private JTextField nickNameField;
032  private JTextField emailField;
033  private JTextField majorField;
034  private JTextField canvasId;
035  private final JComboBox<LetterGrade> letterGraderComboBox;
036  private final JComboBox<Student.Section> enrolledSectionComboBox;
037
038  /**
039   * Creates and lays out a new <code>StudentPanel</code>
040   */
041  public StudentPanel() {
042    this.setLayout(new BorderLayout());
043
044    // Center panel that contains information about the student
045    JPanel infoPanel = new JPanel();
046    infoPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
047    infoPanel.setLayout(new BorderLayout());
048
049    JPanel labels = new JPanel();
050    labels.setLayout(new GridLayout(0, 1));
051    labels.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
052    labels.add(new JLabel("Id:"));
053    labels.add(new JLabel("First name:"));
054    labels.add(new JLabel("Last name:"));
055    labels.add(new JLabel("Nick name:"));
056    labels.add(new JLabel("Email:"));
057    labels.add(new JLabel("SSN:"));
058    labels.add(new JLabel("Major:"));
059    labels.add(new JLabel("Canvas Id:"));
060    labels.add(new JLabel("Letter Grade:"));
061    labels.add(new JLabel("Enrolled Section:"));
062
063    JPanel fields = new JPanel();
064    fields.setLayout(new GridLayout(0, 1));
065    this.idField = new JTextField(10);
066    this.idField.setEditable(false);
067    fields.add(this.idField);
068    this.firstNameField = new JTextField(10);
069    fields.add(this.firstNameField);
070    this.lastNameField = new JTextField(10);
071    fields.add(this.lastNameField);
072    this.nickNameField = new JTextField(10);
073    fields.add(this.nickNameField);
074    this.emailField = new JTextField(15);
075    fields.add(this.emailField);
076    this.majorField = new JTextField(15);
077    fields.add(this.majorField);
078    this.canvasId = new JTextField(10);
079    fields.add(this.canvasId);
080    this.letterGraderComboBox = createLetterGradeComboBox();
081    fields.add(this.letterGraderComboBox);
082    this.enrolledSectionComboBox= createEnrolledSectionComboBox();
083    fields.add(this.enrolledSectionComboBox);
084
085    infoPanel.add(labels, BorderLayout.WEST);
086    infoPanel.add(fields, BorderLayout.CENTER);
087
088    this.add(infoPanel, BorderLayout.NORTH);
089
090    // Add a NotePanel
091    this.notes = new NotesPanel();
092    this.add(notes, BorderLayout.CENTER);
093
094    // Update button
095    JPanel buttons = new JPanel();
096    buttons.setLayout(new FlowLayout());
097    JButton update = new JButton("Update");
098    update.addActionListener(new ActionListener() {
099        public void actionPerformed(ActionEvent e) {
100          if (StudentPanel.this.student != null) {
101            updateStudent(StudentPanel.this.student);
102          }
103        }
104      });
105    buttons.add(update);
106
107    this.add(buttons, BorderLayout.SOUTH);
108  }
109
110  private JComboBox<Student.Section> createEnrolledSectionComboBox() {
111    return createComboBoxWithEnumValues(Student.Section.values());
112  }
113
114  private JComboBox<LetterGrade> createLetterGradeComboBox() {
115    return createComboBoxWithEnumValues(LetterGrade.values());
116  }
117
118  private <E> JComboBox<E> createComboBoxWithEnumValues(E[] values) {
119    Vector<E> vector = new Vector<>();
120    vector.add(null);
121    vector.addAll(Arrays.asList(values));
122    return new JComboBox<>(vector);
123  }
124
125  /**
126   * Clears the contents of the student fields
127   */
128  void clearContents() {
129    this.idField.setText("");
130    this.firstNameField.setText("");
131    this.lastNameField.setText("");
132    this.nickNameField.setText("");
133    this.emailField.setText("");
134    this.majorField.setText("");
135    this.canvasId.setText("");
136    this.letterGraderComboBox.setSelectedItem(null);
137    this.enrolledSectionComboBox.setSelectedItem(null);
138    this.notes.clearNotes();
139  }
140
141  /**
142   * Displays a <code>Student</code> in this
143   * <code>StudentPanel</code>.
144   */
145  public void displayStudent(Student student) {
146    this.student = student;
147    this.clearContents();
148
149//     System.out.println("Displaying student: " +
150//                        student.getDescription());
151
152    // Fill in GUI components
153    this.idField.setText(student.getId());
154
155    String firstName = student.getFirstName();
156    if (firstName != null && !firstName.equals("")) {
157      this.firstNameField.setText(firstName);
158    }
159
160    String lastName = student.getLastName();
161    if (lastName != null && !lastName.equals("")) {
162      this.lastNameField.setText(lastName);
163    }
164
165    String nickName = student.getNickName();
166    if (nickName != null && !nickName.equals("")) {
167      this.nickNameField.setText(nickName);
168    }
169
170    String email = student.getEmail();
171    if (email != null && !email.equals("")) {
172      this.emailField.setText(email);
173    }
174
175    String major = student.getMajor();
176    if (major != null && !major.equals("")) {
177      this.majorField.setText(major);
178    }
179
180    String canvasId = student.getCanvasId();
181    if (canvasId != null && !canvasId.equals("")) {
182      this.canvasId.setText(canvasId);
183    }
184
185    LetterGrade letterGrade = student.getLetterGrade();
186    if (letterGrade != null) {
187      this.letterGraderComboBox.setSelectedItem(letterGrade);
188    }
189
190    Student.Section section = student.getEnrolledSection();
191    if (section != null) {
192      this.enrolledSectionComboBox.setSelectedItem(section);
193    }
194
195    this.notes.setNotable(student);
196  }
197
198  /**
199   * Updates a <code>Student</code> based on the contents of this
200   * <code>StudentPanel</code>.
201   */
202  private void updateStudent(Student student) {
203    String firstName = this.firstNameField.getText();
204    if (firstName != null) {
205      student.setFirstName(firstName);
206    }
207
208    String lastName = this.lastNameField.getText();
209    if (lastName != null) {
210      if (lastName.equals("")) {
211        student.setLastName(null);
212      } else {
213        student.setLastName(lastName);
214      }
215    }
216
217    String nickName = this.nickNameField.getText();
218    if (nickName != null) {
219      if (nickName.equals("")) {
220        student.setNickName(null);
221      } else {
222        student.setNickName(nickName);
223      }
224    }
225
226    String email = this.emailField.getText();
227    if (email != null) {
228      if (email.equals("")) {
229        student.setEmail(null);
230      } else {
231        student.setEmail(email);
232      }
233    }
234
235    String major = this.majorField.getText();
236    if (major != null) {
237      if (major.equals("")) {
238        student.setMajor(null);
239      } else {
240        student.setMajor(major);
241      }
242    }
243    
244    String canvasId = this.canvasId.getText();
245    if (canvasId != null) {
246      if (canvasId.equals("")) {
247        student.setCanvasId(null);
248      } else {
249        student.setCanvasId(canvasId);
250      }
251    }
252
253    LetterGrade letterGrade = (LetterGrade) this.letterGraderComboBox.getSelectedItem();
254    student.setLetterGrade(letterGrade);
255
256    Student.Section section = (Student.Section) this.enrolledSectionComboBox.getSelectedItem();
257    student.setEnrolledSection(section);
258
259    // The NotesPanel takes care of adding notes
260
261//     System.out.println("Updated student: " +
262//                        student.getDescription());
263  }
264
265  /**
266   * Test program
267   */
268  public static void main(String[] args) {
269    final String fileName = args[0];
270    String studentId = args[1];
271
272    GradeBook book = null;
273    try {
274      XmlGradeBookParser parser = new XmlGradeBookParser(fileName);
275      book = parser.parse();
276
277    } catch (FileNotFoundException ex) {
278      System.err.println("** Could not find file: " + ex.getMessage());
279      System.exit(1);
280      
281    } catch (IOException ex) {
282      System.err.println("** IOException during parsing: " + ex.getMessage());
283      System.exit(1);
284
285    } catch (ParserException ex) {
286      System.err.println("** Error during parsing: " + ex);
287      System.exit(1);
288    }
289
290    Student student = book.getStudent(studentId).orElseThrow(cannotFindStudent(studentId));
291
292    StudentPanel studentPanel = new StudentPanel();
293    studentPanel.displayStudent(student);
294
295    JFrame frame = new JFrame("StudentPanel test");
296    final GradeBook theBook = book;
297    frame.addWindowListener(new WindowAdapter() {
298        public void windowClosing(WindowEvent e) {
299         // Write changes to grade book back to file
300          try {
301            XmlDumper dumper = new XmlDumper(fileName);
302            dumper.dump(theBook);
303
304          } catch (IOException ex) {
305            System.err.println("** Error while writing XML file: " + ex);
306          }
307
308          System.exit(1);
309        }
310      });
311
312    frame.getContentPane().add(studentPanel);
313    
314    frame.pack();
315    frame.setVisible(true);
316  }
317
318  @SuppressWarnings("ThrowableInstanceNeverThrown")
319  private static Supplier<IllegalStateException> cannotFindStudent(String studentId) {
320    return () -> new IllegalStateException("Cannot find student with id " + studentId);
321  }
322
323}