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}