001package edu.pdx.cs410J.family; 002 003import edu.pdx.cs410J.family.Person.Gender; 004 005import java.awt.*; 006import java.awt.event.*; 007import java.io.*; 008import java.text.*; 009import java.util.*; 010 011import javax.swing.*; 012import javax.swing.border.*; 013 014/** 015 * This is a dialog for editing a <code>Person</code>. The 016 * <code>Person</code> may or may not already exist. 017 */ 018@SuppressWarnings("serial") 019public class EditPersonDialog extends JDialog { 020 021 // The person we're editing 022 private Person person = null; 023 024 private Person mother; 025 private Person father; 026 private Person child; 027 028 // GUI components we need to hold on to 029 private JTextField idField = new JTextField(); 030 private JTextField firstNameField = new JTextField(); 031 private JTextField middleNameField = new JTextField(); 032 private JTextField lastNameField = new JTextField(); 033 private JTextField dobField = new JTextField(); 034 private JTextField dodField = new JTextField(); 035 private JTextField fatherField = new JTextField("Click to choose"); 036 private JTextField motherField = new JTextField("Click to choose"); 037 private JTextField childField = new JTextField("Click to choose"); 038 private JRadioButton male = new JRadioButton("male", true); 039 private JRadioButton female = new JRadioButton("female"); 040 041 042 /** 043 * Creates a new <code>EditPersonDialog</code> for adding a new 044 * <code>Person</code> to a family tree. 045 * 046 * @param owner 047 * The parent <code>JFrame</code> of this dialog box 048 * @param tree 049 * The existing family tree 050 */ 051 public EditPersonDialog(JFrame owner, FamilyTree tree) { 052 this(owner, "Add New Person", tree); 053 } 054 055 /** 056 * Creates a new <code>EditPersonDialog</code> for editing an 057 * existing Person. 058 */ 059 public EditPersonDialog(Person person, JFrame owner, 060 FamilyTree tree) { 061 this(owner, "Edit Person " + person.getId(), tree); 062 this.person = person; 063 064 // Fill in information about the person 065 this.idField.setText("" + person.getId()); 066 this.idField.setEditable(false); 067 068 if (this.person.getGender() == Person.FEMALE) { 069 female.setSelected(true); 070 female.setEnabled(true); 071 male.setEnabled(false); 072 male.setSelected(false); 073 } 074 075 if (this.person.getGender() == Person.MALE) { 076 male.setSelected(true); 077 male.setEnabled(true); 078 female.setSelected(false); 079 female.setEnabled(false); 080 } 081 082 this.firstNameField.setText(person.getFirstName()); 083 this.middleNameField.setText(person.getMiddleName()); 084 this.lastNameField.setText(person.getLastName()); 085 086 DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM); 087 Date dob = person.getDateOfBirth(); 088 if (dob != null) { 089 this.dobField.setText(df.format(dob)); 090 } 091 Date dod = person.getDateOfDeath(); 092 if (dod != null) { 093 this.dodField.setText(df.format(dod)); 094 } 095 096 this.father = person.getFather(); 097 if (this.father != null) { 098 this.fatherField.setText(this.father.getFullName()); 099 } 100 101 this.mother = person.getMother(); 102 if (this.mother != null) { 103 this.motherField.setText(this.mother.getFullName()); 104 } 105 } 106 107 /** 108 * General constructor called by others. 109 */ 110 private EditPersonDialog(JFrame owner, String title, 111 FamilyTree tree) { 112 super(owner, title, true /* modal */); 113 setupComponents(tree); 114 } 115 116 /** 117 * Adds all of the components to this <code>EditPersonDialog</code>. 118 */ 119 private void setupComponents(final FamilyTree tree) { 120 Container pane = this.getContentPane(); 121 pane.setLayout(new BorderLayout()); 122 123 JPanel infoPanel = new JPanel(); 124 infoPanel.setLayout(new GridLayout(0, 2)); 125 Border infoBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5); 126 infoPanel.setBorder(infoBorder); 127 128 infoPanel.add(new JLabel("id:")); 129 infoPanel.add(idField); 130 131 final ButtonGroup group = new ButtonGroup(); 132 133 group.add(male); 134 male.setActionCommand("male"); 135 infoPanel.add(male); 136 137 group.add(female); 138 female.setActionCommand("female"); 139 infoPanel.add(female); 140 141 infoPanel.add(new JLabel("First name:")); 142 infoPanel.add(firstNameField); 143 144 infoPanel.add(new JLabel("Middle name:")); 145 infoPanel.add(middleNameField); 146 147 infoPanel.add(new JLabel("Last name:")); 148 infoPanel.add(lastNameField); 149 150 infoPanel.add(new JLabel("Date of Birth:")); 151 infoPanel.add(dobField); 152 153 infoPanel.add(new JLabel("Date of Death:")); 154 infoPanel.add(dodField); 155 156 infoPanel.add(new JLabel("Father:")); 157 fatherField.setEditable(false); 158 fatherField.addMouseListener(new MouseAdapter() { 159 public void mouseClicked(MouseEvent e) { 160 ChoosePersonDialog dialog = 161 new ChoosePersonDialog(tree, EditPersonDialog.this); 162 163 dialog.pack(); 164 dialog.setLocationRelativeTo(EditPersonDialog.this); 165 dialog.setVisible(true); 166 167 Person father = dialog.getPerson(); 168 if (father != null) { 169 EditPersonDialog.this.father = father; 170 String fatherName = 171 EditPersonDialog.this.father.getFullName(); 172 EditPersonDialog.this.fatherField.setText(fatherName); 173 } 174 } 175 }); 176 infoPanel.add(fatherField); 177 178 infoPanel.add(new JLabel("Mother:")); 179 motherField.setEditable(false); 180 motherField.addMouseListener(new MouseAdapter() { 181 public void mouseClicked(MouseEvent e) { 182 ChoosePersonDialog dialog = 183 new ChoosePersonDialog(tree, EditPersonDialog.this); 184 185 dialog.pack(); 186 dialog.setLocationRelativeTo(EditPersonDialog.this); 187 dialog.setVisible(true); 188 189 Person mother = dialog.getPerson(); 190 if (mother != null) { 191 EditPersonDialog.this.mother = mother; 192 String motherName = 193 EditPersonDialog.this.mother.getFullName(); 194 EditPersonDialog.this.motherField.setText(motherName); 195 } 196 } 197 }); 198 infoPanel.add(motherField); 199 200 infoPanel.add(new JLabel("Parent of:")); 201 childField.setEditable(false); 202 childField.addMouseListener(new MouseAdapter() { 203 public void mouseClicked(MouseEvent e) { 204 ChoosePersonDialog dialog = 205 new ChoosePersonDialog(tree, EditPersonDialog.this); 206 207 dialog.pack(); 208 dialog.setLocationRelativeTo(EditPersonDialog.this); 209 dialog.setVisible(true); 210 211 Person child = dialog.getPerson(); 212 if (child != null) { 213 EditPersonDialog.this.child = child; 214 String childName = EditPersonDialog.this.child.getFullName(); 215 EditPersonDialog.this.childField.setText(childName); 216 } 217 } 218 }); 219 infoPanel.add(childField); 220 221 pane.add(infoPanel, BorderLayout.NORTH); 222 223 // "OK" and "Cancel" buttons 224 JPanel buttonPanel = new JPanel(); 225 buttonPanel.setLayout(new BoxLayout(buttonPanel, 226 BoxLayout.X_AXIS)); 227 buttonPanel.add(Box.createHorizontalGlue()); 228 229 JButton okButton = new JButton("OK"); 230 okButton.addActionListener(new ActionListener() { 231 public void actionPerformed(ActionEvent e) { 232 // Create a new person based on the information entered in 233 // this dialog 234 int id = 0; 235 try { 236 id = Integer.parseInt(idField.getText()); 237 238 } catch (NumberFormatException ex) { 239 error("Invalid id: " + idField.getText()); 240 return; 241 } 242 243 String text = null; 244 245 text = dobField.getText(); 246 Date dob = null; 247 if (text != null && !text.equals("")) { 248 dob = parseDate(dobField.getText()); 249 if (dob == null) { 250 // Parse error 251 return; 252 } 253 } 254 255 text = dodField.getText(); 256 Date dod = null; 257 if (text != null && !text.equals("")) { 258 dod = parseDate(dodField.getText()); 259 if (dod == null) { 260 // Parse error 261 return; 262 } 263 } 264 265 Gender gender; 266 if (group.getSelection().getActionCommand().equals("male")) { 267 gender = Person.MALE; 268 269 } else { 270 gender = Person.FEMALE; 271 } 272 273 // Okay, everything parsed alright 274 if (person == null) { 275 person = new Person(id, gender); 276 } 277 278 person.setFirstName(firstNameField.getText()); 279 person.setMiddleName(middleNameField.getText()); 280 person.setLastName(lastNameField.getText()); 281 person.setDateOfBirth(dob); 282 person.setDateOfDeath(dod); 283 284 if (mother != null) { 285 person.setMother(mother); 286 } 287 288 if (father != null) { 289 person.setFather(father); 290 } 291 292 if (child != null) { 293 if (person.getGender() == Person.MALE) { 294 child.setFather(person); 295 296 } else { 297 child.setMother(person); 298 } 299 } 300 301 // We're all happy 302 EditPersonDialog.this.dispose(); 303 } 304 }); 305 buttonPanel.add(okButton); 306 307 buttonPanel.add(Box.createHorizontalGlue()); 308 309 JButton cancelButton = new JButton("Cancel"); 310 cancelButton.addActionListener(new ActionListener() { 311 public void actionPerformed(ActionEvent e) { 312 // Read my lips, no new Person! 313 314 EditPersonDialog.this.person = null; 315 316 EditPersonDialog.this.dispose(); 317 } 318 }); 319 buttonPanel.add(cancelButton); 320 321 buttonPanel.add(Box.createHorizontalGlue()); 322 323 pane.add(buttonPanel, BorderLayout.SOUTH); 324 } 325 326 /** 327 * Returns the <code>Person</code> created by this 328 * <code>EditPersonDialog</code>. 329 */ 330 public Person getPerson() { 331 return this.person; 332 } 333 334 /** 335 * Tries very, very hard to parse the a date. We assume that the 336 * text is neither empty nor <code>null</code>. 337 */ 338 private Date parseDate(String text) { 339 DateFormat formats[] = new DateFormat[] { 340 DateFormat.getDateInstance(DateFormat.SHORT), 341 DateFormat.getDateInstance(DateFormat.MEDIUM), 342 DateFormat.getDateInstance(DateFormat.LONG), 343 DateFormat.getDateInstance(DateFormat.FULL), 344 }; 345 346 for (int i = 0; i < formats.length; i++) { 347 DateFormat df = formats[i]; 348 try { 349 Date date = df.parse(text); 350 return date; 351 352 } catch (ParseException ex) { 353 continue; 354 } 355 } 356 357 error("Could not parse date: " + text); 358 return null; 359 } 360 361 /** 362 * Pops up a dialog box with an error message in it. 363 */ 364 private void error(String message) { 365 JOptionPane.showMessageDialog(this, new String[] { message}, 366 "Error.", 367 JOptionPane.ERROR_MESSAGE); 368 } 369 370 /** 371 * Simple test program. 372 */ 373 public static void main(String[] args) { 374 final JFrame frame = new JFrame("Testing EditPersonDialog"); 375 JButton button = new JButton("Click me"); 376 button.addActionListener(new ActionListener() { 377 public void actionPerformed(ActionEvent e) { 378 FamilyTree tree = new FamilyTree(); 379 EditPersonDialog dialog = 380 new EditPersonDialog(frame, tree); 381 dialog.pack(); 382 dialog.setLocationRelativeTo(frame); 383 dialog.setVisible(true); 384 385 Person person = dialog.getPerson(); 386 if (person != null) { 387 tree.addPerson(person); 388 PrettyPrinter pretty = 389 new PrettyPrinter(new PrintWriter(System.out, true)); 390 pretty.dump(tree); 391 } 392 } 393 }); 394 frame.getContentPane().add(button); 395 396 frame.addWindowListener(new WindowAdapter() { 397 public void windowClosing(WindowEvent e) { 398 System.exit(1); 399 } 400 }); 401 frame.pack(); 402 frame.setVisible(true); 403 } 404}