001package edu.pdx.cs410J.family; 002 003import java.awt.*; 004import java.awt.event.*; 005 006import java.net.*; 007 008import java.io.*; 009import javax.swing.*; 010import javax.swing.border.*; 011import javax.swing.event.*; 012 013/** 014 * This class is a <code>JPanel</code> that can be used to display a 015 * family tree. 016 */ 017@SuppressWarnings("serial") 018public class FamilyTreePanel extends JPanel { 019 protected FamilyTree tree = new FamilyTree(); 020 021 // GUI components worth holding onto 022 protected JLabel sourceLocation; 023 protected FamilyTreeList treeList; 024 protected PersonPanel personPanel; 025 026 /** 027 * Creates a new <code>FamilyTreePanel</code> 028 */ 029 public FamilyTreePanel() { 030 this.addComponents(); 031 } 032 033 /** 034 * Adds the GUI components to a <code>FamilyTreePanel</code> 035 */ 036 void addComponents() { 037 System.out.println("Creating Panel"); 038 039 // Set up the content 040 Dimension minSizeLeft = new Dimension(50, 100); 041 this.treeList = new FamilyTreeList(); 042 this.treeList.setToolTipText("Click to select a person in the " + 043 "family tree"); 044 this.treeList.addListSelectionListener(new ListSelectionListener() 045 { 046 public void valueChanged(ListSelectionEvent e) { 047 Person person = 048 FamilyTreePanel.this.treeList.getSelectedPerson(); 049 showPerson(person); 050 } 051 }); 052 this.treeList.setMinimumSize(minSizeLeft); 053 JScrollPane scrollPane = new JScrollPane(this.treeList); 054 scrollPane.setMinimumSize(minSizeLeft); 055 056 JPanel newPersonPanel = null; 057 if (this.canEdit()) { 058 newPersonPanel = new JPanel(); 059 newPersonPanel.setLayout(new BoxLayout(newPersonPanel, 060 BoxLayout.X_AXIS)); 061 newPersonPanel.add(Box.createHorizontalGlue()); 062 JButton newPersonButton = new JButton("New Person"); 063 newPersonButton.setToolTipText("Creates a new person"); 064 newPersonButton.setMnemonic(KeyEvent.VK_N); 065 newPersonButton.addActionListener(new ActionListener() { 066 public void actionPerformed(ActionEvent e) { 067 newPerson(); 068 } 069 }); 070 newPersonPanel.add(newPersonButton); 071 newPersonPanel.add(Box.createHorizontalGlue()); 072 } 073 074 JPanel treePanel = new JPanel(); 075 treePanel.setLayout(new BorderLayout()); 076 treePanel.add(scrollPane, BorderLayout.CENTER); 077 if (this.canEdit()) { 078 treePanel.add(newPersonPanel, BorderLayout.SOUTH); 079 } 080 081 this.personPanel = new PersonPanel(this); 082 083 JSplitPane splitPane = 084 new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treePanel, this.personPanel); 085 086 this.setLayout(new BorderLayout()); 087 this.add(splitPane, BorderLayout.CENTER); 088 089 JPanel sourcePanel = new JPanel(); 090 sourcePanel.setLayout(new BoxLayout(sourcePanel, BoxLayout.X_AXIS)); 091 this.sourceLocation = new JLabel(); 092 this.sourceLocation.setToolTipText("Location of XML file"); 093 sourcePanel.add(this.sourceLocation); 094 sourcePanel.add(Box.createHorizontalGlue()); 095 096 Border sourceBorder = BorderFactory.createEmptyBorder(2, 2, 2, 2); 097 sourcePanel.setBorder(sourceBorder); 098 099 this.add(sourcePanel, BorderLayout.SOUTH); 100 } 101 102 /** 103 * Sets the text displayed in the source location label. 104 */ 105 void setSourceText(String text) { 106 this.sourceLocation.setText(text); 107 } 108 109 /** 110 * Returns <code>true</code> if this GUI can be used to edit a person. 111 */ 112 boolean canEdit() { 113 return false; 114 } 115 116 /** 117 * Sets the <code>Person</code> displayed in the GUI 118 */ 119 void showPerson(Person person) { 120 this.personPanel.showPerson(person); 121 } 122 123 /** 124 * Displays the current <code>Person</code>'s mother 125 */ 126 void displayMother() { 127 Person person = this.treeList.getSelectedPerson(); 128 if (person != null) { 129 this.treeList.setSelectedPerson(person.getMother()); 130 } 131 } 132 133 /** 134 * Displays the current <code>Person</code>'s father 135 */ 136 void displayFather() { 137 Person person = this.treeList.getSelectedPerson(); 138 if (person != null) { 139 this.treeList.setSelectedPerson(person.getFather()); 140 } 141 } 142 143 /** 144 * Returns the <code>FamilyTree</code> being edited. 145 */ 146 FamilyTree getFamilyTree() { 147 return this.tree; 148 } 149 150 /** 151 * Called when the family tree changes dirtiness. Has no effect 152 * with the panel. 153 */ 154 void setDirty(boolean isDirty) { 155 156 } 157 158 /** 159 * Called when a new person is to be created. Has no effect with 160 * the panel. 161 */ 162 void newPerson() { 163 164 } 165 166 /** 167 * Called when a person is to be edited. No effect with the panel. 168 */ 169 void editPerson() { 170 171 } 172 173 /** 174 * Called when a marriage is added. No effect with the panel. 175 */ 176 void addMarriage() { 177 178 } 179 180 /** 181 * Returns the <code>JFrame</code> associated with this GUI. 182 * Returns <code>null</code> for the panel. 183 */ 184 JFrame getFrame() { 185 return null; 186 } 187 188 /** 189 * Sets the source of the XML file displayed in this GUI 190 */ 191 protected void setURLSource(URL url) { 192 try { 193 this.tree = parseSource(url); 194 195 } catch (IOException ex) { 196 System.out.println("source = " + this.sourceLocation + ": " + ex); 197 this.sourceLocation.setText(ex.toString()); 198 return; 199 200 } catch (FamilyTreeException ex) { 201 this.sourceLocation.setText(ex.toString()); 202 return; 203 } 204 205 this.treeList.fillInList(this.tree); 206 this.sourceLocation.setText(url.toExternalForm()); 207 } 208 209 /** 210 * Parses a <code>URL</code> and tries to extract a family tree in 211 * XML format from it. 212 */ 213 protected FamilyTree parseSource(URL url) 214 throws IOException, FamilyTreeException { 215 216 InputStream stream = url.openStream(); 217 218 XmlParser parser = new XmlParser(new InputStreamReader(stream)); 219 return parser.parse(); 220 } 221 222 /** 223 * Creates a <code>FamilyTreePanel</code> that is displayed inside 224 * a <code>JFrame</code> 225 */ 226 public static void main(String[] args) { 227 if (args.length < 1) { 228 System.err.println("** No URL Specified!!"); 229 System.exit(1); 230 } 231 232 URL url = null; 233 try { 234 url = new URL(args[0]); 235 236 } catch (MalformedURLException ex) { 237 System.err.println(ex.toString()); 238 System.exit(1); 239 } 240 241 FamilyTreePanel viewer = new FamilyTreePanel(); 242 viewer.setURLSource(url); 243 244 245 JFrame frame = new JFrame("Family Tree Panel"); 246 frame.getContentPane().add(viewer); 247 248 frame.addWindowListener(new WindowAdapter() { 249 public void windowClosing(WindowEvent e) { 250 System.exit(0); 251 } 252 }); 253 254 frame.pack(); 255 frame.setVisible(true); 256 } 257 258}