001package edu.pdx.cs410J.family;
002
003import java.awt.Component;
004import java.awt.Dimension;
005import java.awt.event.ActionEvent;
006import java.awt.event.ActionListener;
007import java.awt.event.MouseAdapter;
008import java.awt.event.MouseEvent;
009import java.text.DateFormat;
010import java.util.ArrayList;
011import java.util.Date;
012import java.util.Vector;
013
014import javax.swing.BorderFactory;
015import javax.swing.Box;
016import javax.swing.BoxLayout;
017import javax.swing.JButton;
018import javax.swing.JLabel;
019import javax.swing.JList;
020import javax.swing.JPanel;
021import javax.swing.JScrollPane;
022import javax.swing.border.Border;
023
024/**
025 * This class is a <code>JPanel</code> that displays a
026 * <code>Person</code>.
027 */
028@SuppressWarnings("serial")
029public class PersonPanel extends JPanel {
030  private FamilyTreePanel familyGUI;  // Used for callbacks
031
032  private Person person;  // Who are we displaying?
033  private ArrayList<Marriage> marriages = new ArrayList<Marriage>();
034
035  // Some GUI components we care about
036  private JLabel name;
037  private JLabel dob;
038  private JLabel dod;
039  private JLabel fatherName;
040  private JLabel motherName;
041  private JList marriagesList;
042
043
044  /**
045   * Creates a <code>PersonPanel</code> for displaying
046   * <code>Person</code>s
047   */ 
048  public PersonPanel(final FamilyTreePanel familyGUI) {
049    this.familyGUI = familyGUI;
050
051    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
052    
053    JPanel infoPanel = new JPanel();
054    infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.Y_AXIS));
055
056    this.name = new JLabel("Name: ");
057    this.name.setToolTipText("The name of this person");
058    this.name.setAlignmentX(Component.LEFT_ALIGNMENT);
059    infoPanel.add(this.name);
060
061    this.dob = new JLabel("Born: ");
062    this.dob.setToolTipText("The day this person was born");
063    this.dob.setAlignmentX(Component.LEFT_ALIGNMENT);
064    infoPanel.add(this.dob);
065
066    this.dod = new JLabel("Died: ");
067    this.dod.setToolTipText("The day this person died");
068    this.dod.setAlignmentX(Component.LEFT_ALIGNMENT);
069    infoPanel.add(this.dod);
070
071    this.fatherName = new JLabel("Father: ");
072    this.fatherName.setToolTipText("Click to view this person's " +
073                                   "father");
074    this.fatherName.setAlignmentX(Component.LEFT_ALIGNMENT);
075    this.fatherName.addMouseListener(new MouseAdapter() {
076        public void mouseClicked(MouseEvent e) {
077          PersonPanel.this.familyGUI.displayFather();
078        }
079      });
080    infoPanel.add(this.fatherName);
081
082    this.motherName = new JLabel("Mother: ");
083    this.motherName.setToolTipText("Click to view this person's " +
084                                   "mother");
085    this.motherName.setAlignmentX(Component.LEFT_ALIGNMENT);
086    this.motherName.addMouseListener(new MouseAdapter() {
087        public void mouseClicked(MouseEvent e) {
088          PersonPanel.this.familyGUI.displayMother();
089        }
090      });
091    infoPanel.add(motherName);
092
093    Border infoBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5);
094    infoPanel.setBorder(infoBorder);
095
096    this.add(infoPanel);
097
098    JPanel marriagePanel = new JPanel();
099    marriagePanel.setToolTipText("The marriages this person " + 
100                                 "is involed in");
101    marriagePanel.setLayout(new BoxLayout(marriagePanel,
102                                          BoxLayout.Y_AXIS));
103    Border border = BorderFactory.createCompoundBorder(
104                 BorderFactory.createTitledBorder("Marriages"),
105                 BorderFactory.createEmptyBorder(5,5,5,5));
106    marriagePanel.setBorder(border);
107    this.marriagesList = new JList();
108    this.marriagesList.setMinimumSize(new Dimension(100, 30));
109    this.marriagesList.addMouseListener(new MouseAdapter() {
110        public void mouseClicked(MouseEvent e) {
111          if (e.getClickCount() == 2) {
112            // Double-click to edit marriage
113            int index = marriagesList.getSelectedIndex();
114            Marriage marriage = null;
115
116            if (index < marriages.size()) {
117              marriage = (Marriage) marriages.get(index);
118            }
119
120            if (marriage != null && familyGUI.canEdit()) { 
121              EditMarriageDialog dialog = 
122                new EditMarriageDialog(marriage, 
123                                       familyGUI.getFrame(), 
124                                       familyGUI.getFamilyTree());
125              dialog.pack();
126              dialog.setLocationRelativeTo(familyGUI);
127              dialog.setVisible(true);
128              
129              if (dialog.getMarriage() != null) {
130                // Assume a change was made and update person panel
131                familyGUI.setDirty(true);
132                familyGUI.showPerson(person);
133              }
134            }
135          }
136        }
137      });
138
139    JScrollPane scrollPane = new JScrollPane(this.marriagesList);
140    marriagePanel.add(scrollPane);
141
142    // If the GUI can't edit a person, don't bother display the
143    // buttons to do so.
144    if (familyGUI.canEdit()) {
145      JButton addMarriageButton = new JButton("Add Marriage");
146      addMarriageButton.setToolTipText("Notes a marriage involving " +
147                                       "this person"); 
148      addMarriageButton.addActionListener(new ActionListener() {
149          public void actionPerformed(ActionEvent e) {
150            PersonPanel.this.familyGUI.addMarriage();
151          }
152        });
153      JPanel addMarriagePanel = new JPanel();
154      addMarriagePanel.setLayout(new BoxLayout(addMarriagePanel,
155                                               BoxLayout.X_AXIS));
156      addMarriagePanel.add(Box.createHorizontalGlue());
157      addMarriagePanel.add(addMarriageButton);
158      marriagePanel.add(addMarriagePanel);
159      marriagePanel.setAlignmentX(Component.LEFT_ALIGNMENT);
160      this.add(marriagePanel);
161      
162      JPanel editPanel = new JPanel();
163      JButton editButton = new JButton("Edit");
164      editButton.setToolTipText("Click to edit this person");
165      editButton.addActionListener(new ActionListener() {
166          public void actionPerformed(ActionEvent e) {
167            PersonPanel.this.familyGUI.editPerson();
168          }
169        });
170      editPanel.setLayout(new BoxLayout(editPanel, BoxLayout.X_AXIS));
171      editPanel.add(Box.createHorizontalGlue());
172      editPanel.add(editButton);
173      editPanel.add(Box.createHorizontalGlue());
174      editPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
175      this.add(editPanel);
176    }
177
178    this.add(Box.createVerticalGlue());
179
180  }
181
182  /**
183   * Fills in the labels with default text values
184   */
185  private void fillInLabels() {
186    this.name.setText("Name");
187    this.dob.setText("Born:");
188    this.dod.setText("Died:");
189    this.fatherName.setText("Father:");
190    this.motherName.setText("Mother:");
191    this.marriagesList.setListData(new Vector());
192  }
193
194  /**
195   * Displays information about a <code>Person</code> in this
196   * <code>PersonPanel</code>.
197   */
198  public void showPerson(Person person) {
199    this.person = person;
200
201//      System.out.println("Display person: " + person.getFullName());
202
203    // Re-initialize all fields
204    fillInLabels();
205
206    if (this.person == null) {
207      // When no person is selected
208      return;
209    }
210
211    DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
212
213    this.name.setText(person.getFullName());
214
215    Date dob = person.getDateOfBirth();
216    if (dob != null) {
217      this.dob.setText("Born: " + df.format(dob));
218    }
219
220    Date dod = person.getDateOfDeath();
221    if (dod != null) {
222      this.dod.setText("Died: " + df.format(dod));
223    }
224
225    Person father = person.getFather();
226    if (father != null) {
227      this.fatherName.setText("Father: " + father.getFullName());
228    }
229
230    Person mother = person.getMother();
231    if (mother != null) {
232      this.motherName.setText("Mother: " + mother.getFullName());
233    }
234
235    this.marriages = new ArrayList<Marriage>(person.getMarriages());
236    Vector<String> list = new Vector<String>();
237    for (Marriage marriage : person.getMarriages()) {
238      StringBuffer sb = new StringBuffer();
239      Person spouse = (marriage.getHusband().getId() == person.getId()
240                       ? marriage.getWife() 
241                       : marriage.getHusband());
242      sb.append(spouse.getFullName());
243
244      Date date = marriage.getDate();
245      if (date != null) {
246        sb.append(" on " + df.format(date));
247      }
248
249      String location = marriage.getLocation();
250      if (location != null || !location.equals("")) {
251        sb.append(" in " + location);
252      }
253
254      list.add(sb.toString());
255    }
256
257    this.marriagesList.setListData(list);
258  }
259
260  /**
261   * Displays and returns the current person's father
262   */
263  public Person showFather() {
264    Person father = this.person.getFather();
265    if (father != null) {
266      this.showPerson(father);
267    }
268    return father;
269  }
270
271  /**
272   * Displays the current person's mother
273   */
274  public Person showMother() {
275    Person mother = this.person.getMother();
276    if (mother != null) {
277      this.showPerson(mother);
278    }
279    return mother;
280  }
281}