001package edu.pdx.cs410J.family; 002 003import java.awt.BorderLayout; 004import java.awt.Container; 005import java.awt.GridLayout; 006import java.awt.event.ActionEvent; 007import java.awt.event.ActionListener; 008import java.awt.event.MouseAdapter; 009import java.awt.event.MouseEvent; 010import java.text.DateFormat; 011import java.text.ParseException; 012import java.util.Date; 013 014import javax.swing.BorderFactory; 015import javax.swing.Box; 016import javax.swing.BoxLayout; 017import javax.swing.JButton; 018import javax.swing.JDialog; 019import javax.swing.JFrame; 020import javax.swing.JLabel; 021import javax.swing.JOptionPane; 022import javax.swing.JPanel; 023import javax.swing.JTextField; 024import javax.swing.border.Border; 025 026/** 027 * This is a dialog for editing a <code>Marriage</code>. 028 * 029 * @author David Whitlock 030 * @version $Revision: 1.6 $ 031 * @since Fall 2000 032 */ 033@SuppressWarnings("serial") 034public class EditMarriageDialog extends JDialog { 035 036 // The Marriage we're editing 037 private Marriage marriage = null; 038 039 private Person husband = null; 040 private Person wife = null; 041 042 private boolean changeHusband = true; 043 private boolean changeWife = true; 044 045 // GUI components we need to hold on to 046 private JTextField husbandField = new JTextField("Click to choose"); 047 private JTextField wifeField = new JTextField("Click to choose"); 048 private JTextField dateField = new JTextField(); 049 private JTextField locationField = new JTextField(); 050 051 /** 052 * Creates a new <code>EditMarriageField</code> for adding a new 053 * <code>Marriage</code> to a family tree. 054 */ 055 public EditMarriageDialog(JFrame owner, FamilyTree tree) { 056 this(owner, "Add New Marriage", tree); 057 } 058 059 /** 060 * Creates a new <code>EditMarriageDialog</code> for creating a new 061 * marriage involving one person. 062 */ 063 public EditMarriageDialog(Person spouse, JFrame owner, 064 FamilyTree tree) { 065 this(owner, "Creating Marriage", tree); 066 067 if (spouse.getGender() == Person.MALE) { 068 // husband 069 this.husband = spouse; 070 this.husbandField.setText(this.husband.getFullName()); 071 this.husbandField.setEditable(false); 072 this.changeHusband = false; 073 074 } else { 075 // wife 076 this.wife = spouse; 077 this.wifeField.setText(this.wife.getFullName()); 078 this.wifeField.setEditable(false); 079 this.changeWife = false; 080 } 081 082 this.marriage = null; 083 } 084 085 /** 086 * Creates a new <code>EditMarriageDialog</code> for editing an 087 * existing marriage. 088 */ 089 public EditMarriageDialog(Marriage marriage, JFrame owner, 090 FamilyTree tree) { 091 this(owner, "Edit Marriage", tree); 092 this.marriage = marriage; 093 094 // Fill in information about the marriage 095 this.husband = marriage.getHusband(); 096 this.husbandField.setText(this.husband.getFullName()); 097 this.husbandField.setEditable(false); 098 099 this.wife = marriage.getWife(); 100 this.wifeField.setText(this.wife.getFullName()); 101 this.wifeField.setEditable(false); 102 103 Date date = marriage.getDate(); 104 if (date != null) { 105 DateFormat df = DateFormat.getDateInstance(DateFormat.LONG); 106 this.dateField.setText(df.format(date)); 107 } 108 109 String location = marriage.getLocation(); 110 this.locationField.setText(location); 111 } 112 113 /** 114 * General constructor called by others 115 */ 116 private EditMarriageDialog(JFrame owner, String title, 117 FamilyTree tree) { 118 super(owner, title, true /* modal */); 119 setupComponents(tree); 120 } 121 122 /** 123 * Adds all of the components to this <code>EditMarriageDialog</code>. 124 */ 125 private void setupComponents(final FamilyTree tree) { 126 Container pane = this.getContentPane(); 127 pane.setLayout(new BorderLayout()); 128 129 JPanel infoPanel = new JPanel(); 130 infoPanel.setLayout(new GridLayout(4, 2)); 131 Border infoBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5); 132 infoPanel.setBorder(infoBorder); 133 134 infoPanel.add(new JLabel("Husband:")); 135 husbandField.setEditable(false); 136 husbandField.addMouseListener(new MouseAdapter() { 137 public void mouseClicked(MouseEvent e) { 138 if (!changeHusband) { 139 return; 140 } 141 142 ChoosePersonDialog dialog = 143 new ChoosePersonDialog(tree, EditMarriageDialog.this); 144 145 dialog.pack(); 146 dialog.setLocationRelativeTo(EditMarriageDialog.this); 147 dialog.setVisible(true); 148 149 Person husband = dialog.getPerson(); 150 if (husband != null) { 151 EditMarriageDialog.this.husband = husband; 152 String husbandName = 153 EditMarriageDialog.this.husband.getFullName(); 154 EditMarriageDialog.this.husbandField.setText(husbandName); 155 } 156 } 157 }); 158 infoPanel.add(husbandField); 159 160 infoPanel.add(new JLabel("Wife:")); 161 wifeField.setEditable(false); 162 wifeField.addMouseListener(new MouseAdapter() { 163 public void mouseClicked(MouseEvent e) { 164 if (!changeWife) { 165 return; 166 } 167 168 ChoosePersonDialog dialog = 169 new ChoosePersonDialog(tree, EditMarriageDialog.this); 170 171 dialog.pack(); 172 dialog.setLocationRelativeTo(EditMarriageDialog.this); 173 dialog.setVisible(true); 174 175 Person wife = dialog.getPerson(); 176 if (wife != null) { 177 EditMarriageDialog.this.wife = wife; 178 String wifeName = 179 EditMarriageDialog.this.wife.getFullName(); 180 EditMarriageDialog.this.wifeField.setText(wifeName); 181 } 182 } 183 }); 184 infoPanel.add(wifeField); 185 186 infoPanel.add(new JLabel("Date:")); 187 infoPanel.add(dateField); 188 189 infoPanel.add(new JLabel("Location:")); 190 infoPanel.add(locationField); 191 192 pane.add(infoPanel, BorderLayout.NORTH); 193 194 // "OK" and "Cancel" buttons 195 JPanel buttonPanel = new JPanel(); 196 buttonPanel.setLayout(new BoxLayout(buttonPanel, 197 BoxLayout.X_AXIS)); 198 buttonPanel.add(Box.createHorizontalGlue()); 199 200 JButton okButton = new JButton("OK"); 201 okButton.addActionListener(new ActionListener() { 202 public void actionPerformed(ActionEvent e) { 203 // Create a new marriage based on the information entered in 204 // this dialog 205 if (husband == null) { 206 error("Missing husband"); 207 return; 208 } 209 210 if (wife == null) { 211 error("Missing wife"); 212 return; 213 } 214 215 String text = null; 216 217 text = dateField.getText(); 218 Date date = null; 219 if (text != null && !text.equals("")) { 220 date = parseDate(text); 221 if (date == null) { 222 // Parse error 223 return; 224 } 225 } 226 227 // Everything parsed alright 228 if (marriage == null) { 229 marriage = new Marriage(husband, wife); 230 husband.addMarriage(marriage); 231 wife.addMarriage(marriage); 232 } 233 234 marriage.setDate(date); 235 marriage.setLocation(locationField.getText()); 236 237 // We're all happy 238 EditMarriageDialog.this.dispose(); 239 } 240 }); 241 buttonPanel.add(okButton); 242 243 buttonPanel.add(Box.createHorizontalGlue()); 244 245 JButton cancelButton = new JButton("Cancel"); 246 cancelButton.addActionListener(new ActionListener() { 247 public void actionPerformed(ActionEvent e) { 248 // Read my lips, no new Marriage! 249 250 EditMarriageDialog.this.marriage = null; 251 252 EditMarriageDialog.this.dispose(); 253 } 254 }); 255 buttonPanel.add(cancelButton); 256 257 buttonPanel.add(Box.createHorizontalGlue()); 258 259 pane.add(buttonPanel, BorderLayout.SOUTH); 260 } 261 262 /** 263 * Returns the <code>Marriage</code> edited by this 264 * <code>EditMarriageDialog</code>. 265 */ 266 public Marriage getMarriage() { 267 return this.marriage; 268 } 269 270 /** 271 * Tries very, very hard to parse the a date. We assume that the 272 * text is neither empty nor <code>null</code>. 273 */ 274 private Date parseDate(String text) { 275 DateFormat formats[] = new DateFormat[] { 276 DateFormat.getDateInstance(DateFormat.SHORT), 277 DateFormat.getDateInstance(DateFormat.MEDIUM), 278 DateFormat.getDateInstance(DateFormat.LONG), 279 DateFormat.getDateInstance(DateFormat.FULL), 280 }; 281 282 for (int i = 0; i < formats.length; i++) { 283 DateFormat df = formats[i]; 284 try { 285 Date date = df.parse(text); 286 return date; 287 288 } catch (ParseException ex) { 289 continue; 290 } 291 } 292 293 error("Could not parse date: " + text); 294 return null; 295 } 296 297 /** 298 * Pops up a dialog box with an error message in it. 299 */ 300 private void error(String message) { 301 JOptionPane.showMessageDialog(this, new String[] { message}, 302 "Error.", 303 JOptionPane.ERROR_MESSAGE); 304 } 305 306}