001package edu.pdx.cs410J.grader.gradebook.ui;
002
003import edu.pdx.cs410J.ParserException;
004import edu.pdx.cs410J.grader.gradebook.GradeBook;
005import edu.pdx.cs410J.grader.gradebook.Student;
006import edu.pdx.cs410J.grader.gradebook.XmlGradeBookParser;
007
008import javax.swing.*;
009import java.awt.*;
010import java.awt.event.ActionEvent;
011import java.awt.event.ActionListener;
012import java.awt.event.WindowAdapter;
013import java.awt.event.WindowEvent;
014import java.io.FileNotFoundException;
015import java.io.IOException;
016import java.util.*;
017
018/**
019 * A <code>StudentsList</code> is a <code>JList</code> that lists all
020 * of the students in a <code>GradeBook</code> sorted alphabetically
021 * by their last name.
022 */
023@SuppressWarnings("serial")
024public class StudentsList extends JPanel {
025  private static final int SORT_BY_NAME = 1;
026  private static final int SORT_BY_ID = 2;
027
028  private JList list;
029
030  private int howSorted;
031  private ArrayList<Student> studentsByName;
032  private ArrayList<Student> studentsById;
033
034  
035
036  /**
037   * Creates a <code>StudentsList</code> and sets up some initial
038   * parameters.
039   */
040  public StudentsList() {
041    this.howSorted = SORT_BY_NAME;
042
043    // Create the JList
044    this.list = new JList();
045    this.list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
046    this.list.clearSelection();
047
048    // Wrap a ScrollPane around it
049    JScrollPane scrollPane = new JScrollPane(this.list);
050
051    // Create the toggle buttons
052    JRadioButton byName = new JRadioButton("By Name");
053    byName.addActionListener(new ActionListener() {
054        public void actionPerformed(ActionEvent e) {
055          StudentsList.this.howSorted = SORT_BY_NAME;
056          StudentsList.this.displayStudents();
057        }
058      });
059    if (this.howSorted == SORT_BY_NAME) {
060      byName.setSelected(true);
061    }
062
063    JRadioButton byId = new JRadioButton("By ID");
064    byId.addActionListener(new ActionListener() {
065        public void actionPerformed(ActionEvent e) {
066          StudentsList.this.howSorted = SORT_BY_ID;
067          StudentsList.this.displayStudents();
068        }
069      });
070    if (this.howSorted == SORT_BY_ID) {
071      byId.setSelected(true);
072    }
073
074    ButtonGroup bg = new ButtonGroup();
075    bg.add(byName);
076    bg.add(byId);
077
078    JPanel buttonPanel = new JPanel();
079    buttonPanel.setLayout(new FlowLayout());
080    buttonPanel.add(byName);
081    buttonPanel.add(byId);
082
083
084    // Add the components to this JPanel
085    this.setLayout(new BorderLayout());
086    this.add(scrollPane, BorderLayout.CENTER);
087    this.add(buttonPanel, BorderLayout.SOUTH);
088  }
089
090  /**
091   * Reads the contents of a <code>GradeBook</code> and sorts
092   * <code>Student</code>s accordingly.
093   */
094  public void setGradeBook(GradeBook book) {
095    SortedSet<Student> sortedByName = new TreeSet<Student>(new Comparator<Student>() {
096        // Sort by last names
097        public int compare(Student o1, Student o2) {
098          String lastName1 = o1.getLastName();
099          String lastName2 = o2.getLastName();
100
101          if (!lastName1.equalsIgnoreCase(lastName2)) {
102            return lastName1.compareTo(lastName2);            
103          }
104
105          String firstName1 = ((Student) o1).getFirstName();
106          String firstName2 = ((Student) o2).getFirstName();
107
108          if (!firstName1.equalsIgnoreCase(firstName2)) {
109            return firstName1.compareTo(firstName2);            
110          }
111
112          String fullName1 = ((Student) o1).getFullName();
113          String fullName2 = ((Student) o2).getFullName();
114          return fullName1.compareTo(fullName2);
115        }
116
117        public boolean equals(Object o) {
118          return true;
119        }
120      });
121
122    SortedSet<Student> sortedById = new TreeSet<Student>(new Comparator<Student>() {
123        // Sort by ids
124        public int compare(Student o1, Student o2) {
125          String id1 = o1.getId();
126          String id2 = o2.getId();
127          return id1.compareTo(id2);
128        }
129
130        public boolean equals(Object o) {
131          return true;
132        }
133      });
134
135    book.forEachStudent(student -> {
136      sortedByName.add(student);
137      sortedById.add(student);
138    });
139
140    this.studentsByName = new ArrayList<Student>();
141    this.studentsByName.addAll(sortedByName);
142
143    this.studentsById = new ArrayList<Student>();
144    this.studentsById.addAll(sortedById);
145
146    this.displayStudents();
147  }
148
149  /**
150   * Returns a <code>ArrayList</code> of the <code>Student</code>s
151   * currently being displayed sorted by the currently selected
152   * criterion.
153   */
154  private ArrayList getList() {
155    switch(this.howSorted) {
156    case SORT_BY_NAME:
157      return this.studentsByName;
158    case SORT_BY_ID:
159      return this.studentsById;
160    default:
161      return new ArrayList();
162    }
163  }
164  
165  /**
166   * Adds the students in the current grade book to the list in the
167   * appropriate sorted order.
168   */
169  private void displayStudents() {
170    ArrayList list = this.getList();
171    Object[] array = new Object[list.size()];
172
173    Iterator iter = list.iterator();
174    for (int i = 0; iter.hasNext(); i++) {
175      Student student = (Student) iter.next();
176      array[i] = student.getFullName() + " (" + student.getId() + ")";
177    }
178    
179    this.list.setListData(array);
180    this.list.clearSelection();
181  }
182
183  /**
184   * Test program that reads a grade book from an XML file and
185   * displays the students in it using a <code>StudentsList</code>.
186   */    
187  public static void main(String[] args) {
188    if (args.length < 1) {
189      System.err.println("** usage: java StudentsList xmlFile");
190      System.exit(1);
191    }
192
193    String fileName = args[0];
194
195    GradeBook book = null;
196    try {
197      XmlGradeBookParser parser = new XmlGradeBookParser(fileName);
198      book = parser.parse();
199
200    } catch (FileNotFoundException ex) {
201      System.err.println("** Could not find file: " + ex.getMessage());
202      System.exit(1);
203      
204    } catch (IOException ex) {
205      System.err.println("** IOException during parsing: " + ex.getMessage());
206      System.exit(1);
207
208    } catch (ParserException ex) {
209      System.err.println("** Error during parsing: " + ex);
210      System.exit(1);
211    }
212
213    StudentsList list = new StudentsList();
214    list.setGradeBook(book);
215
216    JFrame frame = new JFrame("StudentsList test");
217    frame.addWindowListener(new WindowAdapter() {
218        public void windowClosing(WindowEvent e) {
219          System.exit(1);
220        }
221      });
222
223    frame.getContentPane().add(list);
224    
225    frame.pack();
226    frame.setVisible(true);
227  }
228}