Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/ydp/ui/Gui.java


1   package org.ydp.ui;
2   
3   import java.awt.*;
4   import java.awt.event.*;
5   import java.io.*;
6   import java.beans.*;
7   
8   import javax.swing.*;
9   import javax.swing.filechooser.*;
10  import javax.swing.event.*;
11  import javax.swing.JDialog.*;
12  
13  import java.util.Vector;
14  
15  import org.ydp.gfx.*;
16  import org.ydp.db.*;
17  
18  public class Gui extends JFrame implements ActionListener, MenuListener, ChangeListener {
19      /* constants for use by PhotoInfo's status field */
20      private final String NEW = "not in database";
21      private final String MODIFIED = "different from database";
22      private final String CURRENT = "current with database";
23  
24      /* Objects we use to keep track of our image collection */
25      /* the collection object holds the filenames of the info files for each image */
26      /* the fileinfo object holds all of the miscellaneous information about each image */
27      Vector collection = new Vector();
28      Vector thumbnails = new Vector();
29      Vector filehash = new Vector();
30      File collectionFile;
31      File lastDir = new File("");
32  
33      /* Main frame stuff */
34      JPanel contentpane = new JPanel();
35      JPanel aboutpane = new JPanel();
36      JMenuBar mbar = new JMenuBar();
37      JScrollPane scrollpane = new JScrollPane();
38      JPanel previewPane = new JPanel();
39      JFileChooser chooser;
40      FilePreviewer previewer;
41  
42      static JFrame frame;
43      static Polaroid polaroid;
44  
45      /* About Box stuff */
46      private JDialog aboutBox = null;
47  
48      /* Tool bar stuff */
49      private JToolBar toolbar = new JToolBar();
50      private JToolBar sidetoolbar = new JToolBar();
51  
52      /* Help menu items */
53      private JMenuItem helpItem;
54      private JMenuItem aboutItem;
55  
56      /* miscellaneous information */
57      private int vMajor = 1;
58      private int vMinor = 1;
59      private int vMicro = 3;
60  
61      private int oldwidth = 0;
62      private int oldheight = 0;
63      private boolean changedSinceSave = false;
64      private boolean isNewCollection = true;
65      private PhotoInfo selection;
66      private Options options = new Options();
67  
68      private String appName = "Photo Manager " + vMajor + "." + vMinor + "." + vMicro;
69  
70      /*************************************************************************/
71      /* MAIN METHOD - So I don't lose sight of it anymore!!                   */
72      /*************************************************************************/
73  
74      public static void main(String[] args) {
75    try {
76        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
77    }
78    catch(Exception e) {
79    }
80  
81    frame = new Gui();
82    frame.show();
83      }
84  
85      public Gui() {
86    /* set window title and size */
87    setTitle(appName);
88    setSize(640, 400);
89  
90    /* Make sure we cleanly exit when close window button is pressed */
91    addWindowListener(new WindowAdapter() {
92        public void windowClosing(WindowEvent e) {
93      if(changedSinceSave) {
94          int n = JOptionPane.showConfirmDialog(frame, "Would you like to save your changes before exiting?", appName, JOptionPane.YES_NO_OPTION);
95          if(n == JOptionPane.YES_OPTION) {
96        if(isNewCollection) {
97            saveAsDialog();
98        }
99        else {
100           saveCollection();
101       }
102         }
103     }
104     System.exit(0);
105       }
106   } );
107 
108   /***************************/
109   /* build the side tool bar */
110   /***************************/
111   sidetoolbar.setFloatable(false);
112   sidetoolbar.setOrientation(SwingConstants.VERTICAL);
113   JButton button = null;
114 
115   /* Add photo button */
116   button = new JButton(new ImageIcon("resources/Add24.gif"));
117   button.setToolTipText("Add photo");
118   button.setActionCommand("Add photo");
119   button.addActionListener(this);
120   sidetoolbar.add(button);
121 
122   /* Remove photo button */
123   button = new JButton(new ImageIcon("resources/Remove24.gif"));
124   button.setToolTipText("Remove photo");
125   button.setActionCommand("Remove");
126   button.addActionListener(this);
127   sidetoolbar.add(button);
128 
129   /***************************/
130   /* build the main tool bar */
131   /***************************/
132   toolbar.setFloatable(false);
133   button = null;
134 
135   /* New button */
136   button = new JButton(new ImageIcon("resources/New24.gif"));
137   button.setToolTipText("New Collection");
138   button.setActionCommand("New Collection");
139   button.addActionListener(this);
140   toolbar.add(button);
141 
142   /* Open button */
143   button = new JButton(new ImageIcon("resources/Open24.gif"));
144   button.setToolTipText("Open Collection");
145   button.setActionCommand("Open Collection");
146   button.addActionListener(this);
147   toolbar.add(button);
148 
149   /* Save button */
150   button = new JButton(new ImageIcon("resources/Save24.gif"));
151   button.setToolTipText("Save Collection");
152   button.setActionCommand("Save Collection");
153   button.addActionListener(this);
154   button.setEnabled(false);
155   toolbar.add(button);
156 
157   /* SaveAs button */
158   button = new JButton(new ImageIcon("resources/SaveAs24.gif"));
159   button.setToolTipText("Save Collection as...");
160   button.setActionCommand("Save Collection as...");
161   button.addActionListener(this);
162   toolbar.add(button);
163 
164   /* Toolbar separator */
165   toolbar.addSeparator();
166 
167   /* Refresh thumbnails */
168   button = new JButton(new ImageIcon("resources/Refresh24.gif"));
169   button.setToolTipText("Refresh thumbnails");
170   button.setActionCommand("Refresh");
171   button.addActionListener(this);
172   button.setEnabled(false);
173   toolbar.add(button);
174   
175   /* Upload collection */
176   button = new JButton(new ImageIcon("resources/Up24.gif"));
177   button.setToolTipText("Upload collection");
178   button.setActionCommand("Upload collection");
179   button.addActionListener(this);
180   toolbar.add(button);
181   
182   /* separator */
183   toolbar.addSeparator();
184 
185   /* Preferences button */
186   button = new JButton(new ImageIcon("resources/Preferences24.gif"));
187   button.setToolTipText("Change preferences");
188   button.setActionCommand("Preferences");
189   button.addActionListener(this);
190   toolbar.add(button);
191 
192   /* toolbar separator */
193   toolbar.addSeparator();
194 
195   /* Quit button */
196   button = new JButton(new ImageIcon("resources/Stop24.gif"));
197   button.setToolTipText("Quit");
198   button.setActionCommand("Quit");
199   button.addActionListener(this);
200   toolbar.add(button);
201 
202   /***********************/
203   /* set up the menu bar */
204   /***********************/
205   mbar = new JMenuBar();
206   setJMenuBar(mbar);
207 
208   /***********************/
209   /* build the File menu */
210   /***********************/
211   JMenu menu = new JMenu("File");
212   menu.addMenuListener(this);
213   menu.setMnemonic('F');
214 
215   JMenuItem item = new JMenuItem("New Collection", new ImageIcon("resources/New16.gif"));
216   item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
217   item.addActionListener(this);
218   menu.add(item);
219 
220   item = new JMenuItem("Open Collection", new ImageIcon("resources/Open16.gif"));
221   item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
222   item.addActionListener(this);
223   menu.add(item);
224 
225   item = new JMenuItem("Save Collection", new ImageIcon("resources/Save16.gif"));
226   item.setEnabled(false);
227   item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
228   item.addActionListener(this);
229   menu.add(item);
230 
231   item = new JMenuItem("Save Collection as...", new ImageIcon("resources/SaveAs16.gif"));
232   item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
233   item.addActionListener(this);
234   menu.add(item);
235 
236   menu.addSeparator();
237 
238   item = new JMenuItem("Add photo", new ImageIcon("resources/Add16.gif"));
239   item.addActionListener(this);
240   menu.add(item);
241 
242   item = new JMenuItem("Remove photo", new ImageIcon("resources/Remove16.gif"));
243   item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK));
244   item.addActionListener(this);
245   menu.add(item);
246 
247   menu.addSeparator();
248 
249   item = new JMenuItem("Upload collection", new ImageIcon("resources/Up16.gif"));
250   item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_MASK));
251   item.addActionListener(this);
252   menu.add(item);
253 
254   menu.addSeparator();
255 
256   item = new JMenuItem("Quit");
257   item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK));
258   item.addActionListener(this);
259       menu.add(item);
260 
261   mbar.add(menu);
262 
263   /***********************/
264   /* build the Edit menu */
265   /***********************/
266   menu = new JMenu("Edit");
267   menu.addMenuListener(this);
268   menu.setMnemonic('E');
269 
270   item = new JMenuItem("Preferences");
271   item.addActionListener(this);
272   menu.add(item);
273 
274   mbar.add(menu);
275 
276   /***********************/
277   /* build the Help menu */
278   /***********************/
279   menu = new JMenu("Help");
280   menu.addMenuListener(this);
281   menu.setMnemonic('H');
282 
283   item = new JMenuItem("About", new ImageIcon("resources/About16.gif"));
284   item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_MASK));
285   item.addActionListener(this);
286   menu.add(item);
287   
288   mbar.add(menu);  
289 
290   /* menus are set up, now set up the previewPane */
291   // TODO: figure out a way to make the previewPane re-gridable
292   scrollpane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
293   scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
294   scrollpane.getViewport().addChangeListener(this);
295   scrollpane.getViewport().add(previewPane);
296 
297   /* set up the main window frame */
298   contentpane.setLayout(new BorderLayout());
299   contentpane.add(toolbar, BorderLayout.NORTH);
300   contentpane.add(scrollpane, BorderLayout.CENTER);
301   contentpane.add(sidetoolbar, BorderLayout.WEST);
302   setContentPane(contentpane);
303 
304     }
305 
306     public void stateChanged(ChangeEvent evt) {
307   JViewport tmp = (JViewport)evt.getSource();
308   if(tmp.getHeight() != oldheight || tmp.getWidth() != oldwidth) {
309       refreshPreview();
310   }
311     }
312 
313     public void actionPerformed(ActionEvent evt) {
314   String arg = evt.getActionCommand();
315   System.out.println(arg);
316 
317   if(arg.equals("Quit")) {
318       System.exit(0);
319   }
320     
321   else if(arg.equals("Preferences")) {
322       OptionsGui opts = new OptionsGui(options);
323   }
324 
325   else if(arg.equals("Refresh")) {
326       thumbnails = new Vector();
327       
328       for(int i = 0; i < collection.size(); i++) {
329     PhotoInfo tmp = (PhotoInfo)collection.elementAt(i);
330     File file = new File(tmp.getFilePath() + tmp.getFileName());
331     ImageIcon thumbnail = new PhotoPreview(file, 80).getThumbnail();
332     thumbnails.insertElementAt(thumbnail, thumbnails.size());
333           }
334       refreshPreview();
335   }
336 
337   else if(arg.equals("New Collection")) {
338       if(changedSinceSave) {
339           int n = JOptionPane.showConfirmDialog(frame, "Would you like to save your changes first?", appName, JOptionPane.YES_NO_OPTION);
340     if(n == JOptionPane.YES_OPTION) {
341         if(isNewCollection) {
342             saveAsDialog();
343         }
344         else {
345       saveCollection();
346         }
347     }
348       }
349 
350       collection = new Vector();
351       thumbnails = new Vector();
352       filehash = new Vector();
353       
354       collectionFile = null;
355       changedSinceSave = false;
356       isNewCollection = true;
357       JMenu mnu = (JMenu)mbar.getComponent(0);
358       JMenuItem itm = (JMenuItem)mnu.getItem(3);
359       itm.setEnabled(false);
360       JButton btn = (JButton)toolbar.getComponentAtIndex(2);
361       btn.setEnabled(false);
362       
363       refreshPreview();
364   }
365 
366   else if(arg.equals("Save Collection")) {
367       saveCollection();
368   }
369   
370   else if(arg.equals("Save Collection as...")) {
371       saveAsDialog();
372   }
373 
374   else if(arg.equals("Open Collection")) {
375       if(changedSinceSave) {
376           int n = JOptionPane.showConfirmDialog(frame, "Would you like to save your changes first?", appName, JOptionPane.YES_NO_OPTION);
377     if(n == JOptionPane.YES_OPTION) {
378         if(isNewCollection) {
379             saveAsDialog();
380         }
381         else {
382       saveCollection();
383         }
384     }
385       }
386       
387       /**************************/
388       /* configure file chooser */
389       /**************************/
390       chooser = new JFileChooser();
391       previewer = new FilePreviewer(chooser);
392       chooser.addChoosableFileFilter(new YDPFilter());
393       chooser.setAccessory(previewer);
394       chooser.setDialogType(JFileChooser.OPEN_DIALOG);
395 
396       int retval = chooser.showDialog(frame, null);
397       if(retval == JFileChooser.APPROVE_OPTION) {
398     File theFile = chooser.getSelectedFile();
399     if(theFile != null) {
400         try {
401       loadCollection(theFile);
402         }
403         catch(Exception e) {
404         }
405     }
406       }
407   }
408 
409   else if(arg.equals("Upload collection") && !collection.isEmpty()) {
410       Database db = new Database();
411       db.setConnectionURL(options.getDBAddress());
412       db.setDBName(options.getDBName());
413       db.setUser(options.getDBuser());
414       db.setPass(options.getDBpass());
415 
416       db.connect();
417       db.create();
418       for(int i = 0; i < collection.size(); i++) {
419     PhotoInfo p = (PhotoInfo)collection.elementAt(i);
420     PhotoInfo pinfo = p;
421 
422     //System.out.println(p.getStatus());
423     Vector v = p.toVector();
424     if(db.insert(v)) {
425         System.out.println("Adding new photo");
426         p.setStatus(CURRENT);
427         collection.setElementAt(p, collection.indexOf(pinfo));
428     }
429     else {
430         if(db.update(v)) {
431       System.out.println("Updating old photo");
432       p.setStatus(CURRENT);
433       collection.setElementAt(p, collection.indexOf(pinfo));
434         }
435             else {
436       System.out.println("Could not insert or update photo");
437         }
438     }
439       }
440       db.close();
441   }
442 
443   else if(arg.equals("Add photo")) {
444       /**************************/
445       /* configure file chooser */
446       /**************************/
447       chooser = new JFileChooser(lastDir);
448       chooser.setMultiSelectionEnabled(true);
449       previewer = new FilePreviewer(chooser);
450       chooser.addChoosableFileFilter(new JpegFilter());
451       chooser.setAccessory(previewer);
452       chooser.setDialogType(JFileChooser.OPEN_DIALOG);
453 
454       int retval = chooser.showDialog(frame, null);
455       if(retval == JFileChooser.APPROVE_OPTION) {
456     File theFile = chooser.getSelectedFile();
457     if(theFile != null) {
458         File[] files = chooser.getSelectedFiles();
459 
460         /* add many photos :-) */
461         if(chooser.isMultiSelectionEnabled() && files != null && files.length > 1) {
462       double nrFiles = files.length;
463       //JProgressBar progress = new JProgressBar(0, files.length);
464       //JFrame statusdlg = new JFrame();
465       //statusdlg.setSize(200,100);
466       //statusdlg.getContentPane().add(progress);
467       //statusdlg.show();
468       
469       String filenames = "";
470       for(int i = 0; i < files.length; i++) {
471           try {
472         File file = files[i];
473         String path = file.getCanonicalPath();
474         //progress.setValue(i+1);
475         PhotoInfo pinfo = new PhotoInfo(file);
476         pinfo.setURL(options.getBaseURL() + pinfo.getFileName());
477         pinfo.setThumbPath(options.getThumbPath());
478         pinfo.setThumbName("thumb_" + pinfo.getFileName());
479         pinfo.setThumbURL(options.getThumbURL() + pinfo.getThumbName());
480         
481         boolean inCollection = false;
482       
483         lastDir = new File(pinfo.getFilePath());
484 
485         if(filehash.indexOf(pinfo.getFilePath() + pinfo.getFileName()) < 0) {
486             ImageIcon thumbnail;
487             collection.insertElementAt(pinfo, collection.size());
488             if(options.getMakeThumbs()) {
489           FileOutputStream out = new FileOutputStream(pinfo.getThumbPath() + pinfo.getThumbName());
490           thumbnail = new PhotoPreview(file, 160).getThumbnail();
491           JpegEncoder enc = new JpegEncoder(thumbnail.getImage(), 100, out);
492           enc.Compress();
493           out.close();
494             }
495   
496             thumbnail = new PhotoPreview(file, 80).getThumbnail();
497             thumbnails.insertElementAt(thumbnail, thumbnails.size());
498             
499             System.out.println("Image number " + (i+1) + " of " + files.length + " loaded");
500             double current = i+1;
501             double x = current / nrFiles;
502             x = x * 100;
503             System.out.println((int)x + "% completed");
504             filehash.insertElementAt(pinfo.getFilePath() + pinfo.getFileName(), filehash.size());
505   
506             changedSinceSave = true;
507         
508             if(options.isShowingInfo()) {
509           polaroid = new Polaroid(pinfo);
510           polaroid.show();
511             }
512         }
513           }
514           catch(IOException e) {
515         System.out.println("Something seems terribly wrong here...");
516         System.out.println(e);
517           }
518       }
519       refreshPreview();      
520         }
521 
522         else if(theFile.isDirectory()) {
523       /* TODO: Add support for recursively importing a directory of photos */
524       //JOptionPane.showMessageDialog(frame, "You chose this directory: " + chooser.getSelectedFile().getPath());
525         }
526 
527         /* add the photo to the collection */
528         else {
529       try {
530           File file = chooser.getSelectedFile();
531           String path = file.getCanonicalPath();
532           PhotoInfo pinfo = new PhotoInfo(file);
533           pinfo.setURL(options.getBaseURL() + pinfo.getFileName());
534           pinfo.setThumbPath(options.getThumbPath());
535           pinfo.setThumbName("thumb_" + pinfo.getFileName());
536           pinfo.setThumbURL(options.getThumbURL() + pinfo.getThumbName());
537           boolean inCollection = false;
538       
539           lastDir = new File(pinfo.getFilePath());
540           /* check to make sure we're not adding a duplicate */
541           for(int i = 0; i < collection.size(); i++) {
542         PhotoInfo tmp = (PhotoInfo) collection.elementAt(i);
543         if(path.equals(tmp.getFileName())) {
544             inCollection = true;
545             i = collection.size();
546         }
547           }
548 
549           if(filehash.indexOf(file.getPath()) < 0) {
550         collection.insertElementAt(pinfo, collection.size());
551         ImageIcon thumbnail;
552         
553         if(options.getMakeThumbs()) {
554             FileOutputStream out = new FileOutputStream(pinfo.getThumbPath() + pinfo.getThumbName());
555             thumbnail = new PhotoPreview(file, 160).getThumbnail();
556             JpegEncoder enc = new JpegEncoder(thumbnail.getImage(), 100, out);
557             enc.Compress();
558             out.close();
559         }
560         thumbnail = new PhotoPreview(file, 80).getThumbnail();
561         thumbnails.insertElementAt(thumbnail, thumbnails.size());
562   
563         changedSinceSave = true;
564         
565         filehash.insertElementAt(file.getPath(), filehash.size());
566         refreshPreview();      
567         
568         if(options.isShowingInfo()) {
569             polaroid = new Polaroid(pinfo);
570             polaroid.show();
571         }
572           }
573       }
574       catch(IOException e) {
575           System.out.println("Something seems terribly wrong here...");
576           System.out.println(e);
577       }
578         }  
579     }
580       }
581   }
582 
583   else if(arg.equals("Remove") || arg.equals("Remove photo")) {
584       if(selection != null) {
585     filehash.removeElementAt(filehash.indexOf(selection.getFilePath() + selection.getFileName()));
586     thumbnails.removeElementAt(collection.indexOf(selection));
587     collection.removeElementAt(collection.indexOf(selection));
588     for(int i = 0; i < collection.size(); i++) {
589         System.out.println("Collection item #" + i);
590         System.out.println(collection.elementAt(i));
591     }
592     selection = null;
593     refreshPreview();
594       }
595   }
596   
597         else if(arg.equals("About")) { 
598       if (aboutBox == null) { // first time init of about box
599           Box b = Box.createVerticalBox();
600     
601     Font font = new Font("Dialog", Font.BOLD, 14);
602     JLabel label = null;
603     
604     JPanel aboutPanel = new AboutPanel();
605       
606     aboutPanel.setLayout(new BorderLayout());
607         
608     aboutBox = new JDialog(this, appName, false);
609     aboutBox.getContentPane().add(aboutPanel, BorderLayout.CENTER); 
610 
611 //    b.add(Box.createHorizontalStrut(30));
612     b.add(Box.createVerticalStrut(30));
613     
614     label = new JLabel("About " + appName + "\n");
615     label.setForeground(Color.blue);
616     label.setFont(font);
617     b.add(label);
618     
619           label = new JLabel("\n");
620     label.setForeground(Color.blue);
621     label.setFont(font);
622     b.add(label);
623     
624           label = new JLabel("Created 2001");
625     label.setForeground(Color.blue);
626     label.setFont(font);
627     b.add(label);
628 
629           label = new JLabel("We are:");
630     label.setForeground(Color.blue);
631     label.setFont(font);
632     b.add(label);
633 
634           label = new JLabel("Lane Schwartz, Jeff Lynn, Michelle Meyer");
635     label.setForeground(Color.blue);
636     label.setFont(font);
637     b.add(label);
638 
639         label = new JLabel("Charles Scheidecker, and Tyler Reihmann");
640     label.setForeground(Color.blue);
641     label.setFont(font);
642     b.add(label);
643 
644     b.add(Box.createVerticalStrut(60));
645 
646     Box spacer = Box.createVerticalBox();
647     spacer.add(Box.createHorizontalStrut(50));
648     aboutPanel.add(spacer, "West");
649     
650     spacer = Box.createVerticalBox();
651     spacer.add(Box.createHorizontalStrut(130));
652     aboutPanel.add(spacer, "East");
653           aboutPanel.add(b, "Center");
654 
655     JPanel buttonpanel = new JPanel();
656     buttonpanel.setOpaque(false);
657     JButton button = (JButton) buttonpanel.add(new JButton("OK"));
658     aboutPanel.add(buttonpanel, BorderLayout.SOUTH);
659 
660     button.addActionListener(new OkAction(aboutBox));
661 
662     aboutBox.setResizable(false);
663     aboutBox.pack();
664       }
665       aboutBox.show();
666         }
667 
668     }
669 
670     public int roundup(double d)
671     {
672   int x = (int) d;
673   if(d > x) {
674       x++;
675   }
676   return x;
677     }
678 
679     public synchronized void refreshPreview() {
680   // TODO: Rewrite this so it's more efficient
681   // Separate into two functions, one for adding/removing,
682   // and one for refreshing.  This should fix the scrollbar problem.
683   PhotoInfo pinfo;
684   scrollpane.getViewport().remove(previewPane);
685 
686   int nrRows;
687   int nrCols = scrollpane.getViewport().getWidth() / 90;
688 
689   if(collection.size() > nrCols) {
690       double x = (double) collection.size() / (double) nrCols;
691       nrRows = roundup(x);
692   }
693   else {  
694       nrRows = 1;
695   }
696 
697   previewPane = new JPanel();
698   previewPane.setLayout(new GridLayout(nrRows, nrCols));
699   
700   for(int i = 0; i < collection.size(); i++) {
701       pinfo = (PhotoInfo)collection.elementAt(i);    
702       ImageIcon thumbnail = (ImageIcon)thumbnails.elementAt(i);
703     
704       JPanel preview = new JPanel(new BorderLayout());
705       JLabel prev = new JLabel(thumbnail);
706       prev.setToolTipText(pinfo.getFileName());
707       prev.addMouseListener(new ClickListener(pinfo));
708 
709       preview.addMouseListener(new ClickListener(pinfo));
710       preview.add(prev, "Center");
711 
712       Box b;
713       b = Box.createVerticalBox();
714       b.add(Box.createHorizontalStrut(5));
715       preview.add(b, "West");
716       b = Box.createVerticalBox();
717       b.add(Box.createHorizontalStrut(5));
718       preview.add(b, "East");
719       b = Box.createHorizontalBox();
720       b.add(Box.createVerticalStrut(5));
721       preview.add(b, "North");
722       b = Box.createHorizontalBox();
723       b.add(Box.createVerticalStrut(5));
724       preview.add(b, "South");
725 
726       if(selection == pinfo) {
727     preview.setBackground(Color.blue);
728       }
729 
730       previewPane.add(preview);
731       //System.out.println("Collection item #" + i);
732       //System.out.println(pinfo);
733   }
734 
735   scrollpane.getViewport().add(previewPane);
736   oldwidth = scrollpane.getViewport().getWidth();
737   oldheight = scrollpane.getViewport().getHeight();
738     }
739 
740     public void saveAsDialog() {
741   /**************************/
742   /* configure file chooser */
743   /**************************/
744   chooser = new JFileChooser();
745   previewer = new FilePreviewer(chooser);
746   chooser.addChoosableFileFilter(new YDPFilter());
747   chooser.setAccessory(previewer);
748   chooser.setDialogType(JFileChooser.SAVE_DIALOG);
749 
750   int retval = chooser.showSaveDialog(frame);
751   if(retval == JFileChooser.APPROVE_OPTION) {
752       File theFile = chooser.getSelectedFile();
753       if(theFile != null) {
754           try {
755             saveCollection(theFile);
756         }
757     catch(Exception e) {
758     }
759       }
760   }
761     }
762 
763     class AboutPanel extends JPanel {
764   ImageIcon aboutImage = null;
765   
766   public AboutPanel() {
767       aboutImage = new ImageIcon("resources/YdP.gif");
768       setOpaque(false);
769   }
770   
771   public void paint(Graphics g) {
772       aboutImage.paintIcon(this, g, 0, 0);
773       super.paint(g);
774   }
775     }
776     
777     public void menuSelected(MenuEvent evt) {
778     }
779 
780     public void menuDeselected(MenuEvent evt) {
781     }
782 
783     public void menuCanceled(MenuEvent evt) {
784     }
785 
786     /* save collection as... method */
787     public void saveCollection(File f) {
788         try {
789       //f = new File("/home/scheidch/cs/cs56/java/collection.ydp");
790             ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f.getPath()));
791             //ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("collection.ydp"));
792             collectionFile = f;
793       
794       String name = new String(f.getName());
795       String loc = new String(f.getPath());
796       loc = loc.substring(0, loc.length() - name.length());
797       
798             System.out.println("Saving collection as " + name);
799       System.out.println("Location of collection is " + loc);
800 
801       out.writeObject(new String("YDPcollection"));
802       out.writeInt(collection.size());
803       
804             for(int i = 0; i < collection.size(); i++) {
805                 out.writeObject(collection.elementAt(i));
806                 //System.out.println(collection.elementAt(i));
807             }
808       isNewCollection = false;
809       changedSinceSave = false;
810       JMenu mnu = (JMenu)mbar.getComponent(0);
811       JMenuItem itm = (JMenuItem)mnu.getItem(3);
812       itm.setEnabled(true);
813       JButton btn = (JButton)toolbar.getComponentAtIndex(2);
814       btn.setEnabled(true);
815       
816       out.flush();
817             out.close();
818         }
819         catch(Exception e) {
820             System.out.println(e);
821         }
822     }
823 
824     /* save collection method */
825     public void saveCollection() {
826   saveCollection(collectionFile);
827     }
828 
829     /* open collection method */
830     public void loadCollection(File f) {
831         try {
832             ObjectInputStream in = new ObjectInputStream(new FileInputStream(f.getPath()));
833             PhotoInfo tmp = new PhotoInfo();
834 
835       String hdr = (String)in.readObject();
836       if(hdr.equals("YDPcollection")) {  
837     scrollpane.getViewport().remove(previewPane);
838     previewPane = new JPanel();
839     previewPane.setLayout(new GridLayout(0,6));
840         
841         collection = new Vector();
842     thumbnails = new Vector();
843     filehash = new Vector();
844     collectionFile = f;
845         
846     int nrItems = in.readInt();
847 
848     for(int i = 0; i < nrItems; i++) {
849               tmp = (PhotoInfo) in.readObject();
850         ImageIcon thumbnail = new PhotoPreview(new File(tmp.getThumbPath() + tmp.getThumbName()), 80).getThumbnail();
851                   //System.out.println("Added new item to collection at index " + collection.size());
852         filehash.insertElementAt(tmp.getFilePath() + tmp.getFileName(), filehash.size());
853                   collection.insertElementAt(tmp, collection.size());
854         thumbnails.insertElementAt(thumbnail, thumbnails.size());
855         System.out.println("Image number " + (i+1) + " of " + nrItems + " loaded");
856         double current = i+1;
857         double x = current / nrItems;
858         x = x * 100;
859         System.out.println((int)x + "% completed");
860                   //System.out.println(tmp);
861           }
862     refreshPreview();
863       }
864       else {
865     // TODO: Make some kind of dialog to inform user about this
866     // technically we should never reach this point but it could happen
867     System.out.println("Not a valid photo collection file");
868       }
869       changedSinceSave = false;
870       isNewCollection = false;
871       JMenu mnu = (JMenu)mbar.getComponent(0);
872       JMenuItem itm = (JMenuItem)mnu.getItem(3);
873       itm.setEnabled(true);
874       JButton btn = (JButton)toolbar.getComponentAtIndex(2);
875       btn.setEnabled(true);
876 
877       in.close();
878         }
879         catch(Exception e) {
880             //System.out.println(e);
881       System.out.println("Not a valid photo collection file");
882         }
883     }
884 
885     class OkAction extends AbstractAction {
886   JDialog aboutBox;
887 
888         protected OkAction(JDialog aboutBox) {
889             super("OkAction");
890       this.aboutBox = aboutBox;
891         }
892 
893         public void actionPerformed(ActionEvent e) {
894       aboutBox.setVisible(false);
895   }
896     }
897 
898 
899 
900 
901 
902     /**
903      * the Polaroid class acts as the user's window to the editable
904      * information that each photo in the collection has.
905      *
906      *
907      * @author Charles Scheidecker
908      */
909      
910     class Polaroid extends JDialog implements ActionListener, CaretListener {
911   /* Main frame stuff */
912   JPanel contentpane = new JPanel();
913   JScrollPane scrollpane = new JScrollPane();
914   PhotoInfo photoInfo = null;
915   PhotoInfo origPhotoInfo = null;
916   PhotoPanel photoPanel = null;
917 
918   boolean pressedCancel = false;
919 
920   public Polaroid() {  
921       photoInfo = new PhotoInfo();
922       origPhotoInfo = new PhotoInfo();
923       photoPanel = new PhotoPanel();
924       
925       setupWindow();
926   }
927   
928   public Polaroid(PhotoInfo info) {  
929       photoInfo = (PhotoInfo)info.clone();
930       origPhotoInfo = info;
931       photoPanel = new PhotoPanel(info);
932     
933       setupWindow();
934   }
935 
936   private void setupWindow() {
937           setDefaultCloseOperation(DISPOSE_ON_CLOSE);
938           setSize(250, 400);
939       setResizable(false);
940           setTitle(photoInfo.getFileName());
941 
942           /* Close window on close button press */
943           addWindowListener(new WindowAdapter() {
944     public void windowClosing(WindowEvent e) {
945         if(!origPhotoInfo.equals(photoInfo)) {
946       if(!pressedCancel) {
947           int n = JOptionPane.showConfirmDialog(frame, "Would you like to save your changes first?", appName, JOptionPane.YES_NO_OPTION);
948           if(n == JOptionPane.YES_OPTION) {
949         commitChanges();
950           }
951       }
952         }
953         photoPanel.closeWindow();
954      }
955       } );
956   
957       contentpane.setLayout(new BorderLayout());
958 
959       JPanel buttonPanel = new JPanel();
960       JPanel topPanel = new JPanel();
961       JPanel panel = new JPanel();
962       JButton button = null;
963       JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP);
964       JPanel textPanel = new JPanel();
965       
966       JTextField text;
967       JComboBox combo;
968       Vector list;
969       JLabel label;
970 
971       Box b;
972 
973       /* Photo Panel goes on top */
974       topPanel.setLayout(new BorderLayout());
975       topPanel.add(photoPanel, "Center");
976       
977       /* Remove Photo, Ok, and Cancel go on the bottom */
978       panel = new JPanel();
979       panel.setLayout(new BorderLayout());
980       buttonPanel.setLayout(new BorderLayout());
981       
982       b = Box.createVerticalBox();
983       b.add(Box.createHorizontalStrut(10));
984       button = new JButton("Remove Photo");
985       button.addActionListener(this);
986       b.add(button);
987       panel.add(b, "West");
988       
989       b = Box.createHorizontalBox();
990       button = new JButton("Ok");
991       button.addActionListener(this);
992       b.add(button);
993 
994           b.add(Box.createHorizontalStrut(5));
995       button = new JButton("Cancel");
996       button.addActionListener(this);
997       b.add(button);
998       b.add(Box.createHorizontalStrut(10));
999       panel.add(b, "East");
1000
1001      b = Box.createVerticalBox();
1002      b.add(Box.createVerticalStrut(10));
1003      buttonPanel.add(b, "North");
1004      b = Box.createVerticalBox();
1005      b.add(Box.createVerticalStrut(10));
1006      buttonPanel.add(b, "South");
1007      b = Box.createHorizontalBox();
1008      b.add(Box.createHorizontalStrut(10));
1009      buttonPanel.add(b, "West");
1010      b = Box.createHorizontalBox();
1011      b.add(Box.createHorizontalStrut(10));
1012      buttonPanel.add(b, "East");
1013      buttonPanel.add(panel, "Center");
1014
1015      /* Info Tabs go in the middle */
1016      /* Photo Info tab
1017         Provides text fields with information specific 
1018         to this photo
1019      */
1020      // FIXME: minor bug with images that don't have EXIF tags
1021      // causes fields that should have default values to be empty
1022      label = new JLabel("Date taken");
1023      text = new JTextField(10);
1024      text.setText(photoInfo.getDateOriginal());
1025      text.setActionCommand("dateOriginal");
1026      text.addActionListener(this);
1027      text.addCaretListener(this);
1028      textPanel.add(label);
1029      textPanel.add(text);
1030
1031      panel = new JPanel();
1032      panel.setLayout(new BorderLayout());
1033      textPanel.setLayout(new GridLayout(7,2,5,1));
1034      label = new JLabel("Time taken");
1035      text = new JTextField(10);
1036      text.setText(photoInfo.getTimeOriginal());
1037      text.setActionCommand("timeOriginal");
1038      text.addActionListener(this);
1039      text.addCaretListener(this);
1040      textPanel.add(label);
1041      textPanel.add(text);
1042
1043      label = new JLabel("Light Source");
1044      list = new Vector();
1045      list.insertElementAt("Unknown", list.size());
1046      list.insertElementAt("Daylight", list.size());
1047      list.insertElementAt("Flourescent", list.size());
1048      list.insertElementAt("Tungsten", list.size());
1049      list.insertElementAt("Standard light A", list.size());
1050      list.insertElementAt("Standard light B", list.size());
1051      list.insertElementAt("Standard light C", list.size());
1052      list.insertElementAt("D55", list.size());
1053      list.insertElementAt("D65", list.size());
1054      list.insertElementAt("D75", list.size());
1055      list.insertElementAt("Other", list.size());
1056      list.insertElementAt("Reserved", list.size());
1057      combo = new JComboBox(list);
1058      if(photoInfo.getLightSource() != null) {
1059    combo.setSelectedItem(photoInfo.getLightSource());
1060      }
1061      else {
1062    combo.setSelectedItem("Unknown");
1063    photoInfo.setLightSource("Unknown");
1064      }
1065      combo.setActionCommand("lightSource");
1066      combo.addActionListener(this);
1067      combo.setEditable(false);
1068      textPanel.add(label);
1069      textPanel.add(combo);
1070      
1071      label = new JLabel("Flash");
1072      list = new Vector();
1073      list.insertElementAt("Flash off", list.size());
1074      list.insertElementAt("Flash on", list.size());
1075      list.insertElementAt("Strobe off", list.size());
1076      list.insertElementAt("Strobe on", list.size());
1077      list.insertElementAt("Reserved", list.size());
1078      combo = new JComboBox(list);
1079      if(photoInfo.getFlash() != null) {
1080    combo.setSelectedItem(photoInfo.getFlash());
1081      }
1082      else {
1083    combo.setSelectedItem("Flash off");
1084    photoInfo.setFlash("Flash off");
1085      }
1086      combo.setActionCommand("flash");
1087      combo.setEditable(false);
1088      combo.addActionListener(this);
1089      textPanel.add(label);
1090      textPanel.add(combo);
1091
1092      label = new JLabel("Exposure Time");
1093      text = new JTextField(10);
1094      text.setText(photoInfo.getExposureTime());
1095      text.setActionCommand("exposureTime");
1096      text.addActionListener(this);
1097      text.addCaretListener(this);
1098      textPanel.add(label);
1099      textPanel.add(text);
1100
1101      label = new JLabel("Exposure Program");
1102      list = new Vector();
1103      list.insertElementAt("Not defined", list.size());
1104      list.insertElementAt("Manual", list.size());
1105      list.insertElementAt("Normal Program", list.size());
1106      list.insertElementAt("Aperture Priority", list.size());
1107      list.insertElementAt("Shutter Priority", list.size());
1108      list.insertElementAt("Creative Program", list.size());
1109      list.insertElementAt("Action Program", list.size());
1110      list.insertElementAt("Portrait Mode", list.size());
1111      list.insertElementAt("Landscape Mode", list.size());
1112      list.insertElementAt("Reserved", list.size());
1113      combo = new JComboBox(list);
1114      if(photoInfo.getExposureProgram() != null) {
1115    combo.setSelectedItem(photoInfo.getExposureProgram());
1116      }
1117      else {
1118    combo.setSelectedItem("Not defined");
1119    photoInfo.setExposureProgram("Not defined");
1120      }
1121      combo.setActionCommand("exposureProgram");
1122      combo.setEditable(false);
1123      combo.addActionListener(this);
1124      textPanel.add(label);
1125      textPanel.add(combo);
1126
1127      label = new JLabel("Exposure Metering Mode");
1128      list = new Vector();
1129      list.insertElementAt("Unknown", list.size());
1130      list.insertElementAt("Average", list.size());
1131      list.insertElementAt("Center Weighted Average", list.size());
1132      list.insertElementAt("Spot", list.size());
1133      list.insertElementAt("MultiSpot", list.size());
1134      list.insertElementAt("Pattern", list.size());
1135      list.insertElementAt("Partial", list.size());
1136      list.insertElementAt("Other", list.size());
1137      list.insertElementAt("Reserved", list.size());
1138      combo = new JComboBox(list);
1139      if(photoInfo.getExposureMeteringMode() != null) {
1140    combo.setSelectedItem(photoInfo.getExposureMeteringMode());
1141      }
1142      else {
1143    combo.setSelectedItem("Unknown");
1144    photoInfo.setExposureMeteringMode("Unknown");
1145      }
1146      combo.setEditable(false);
1147      combo.setActionCommand("meteringMode");
1148      combo.addActionListener(this);
1149      textPanel.add(label);
1150      textPanel.add(combo);
1151
1152      b = Box.createVerticalBox();
1153      b.add(Box.createHorizontalStrut(10));
1154      panel.add(b, "West");
1155      b = Box.createVerticalBox();
1156      b.add(Box.createHorizontalStrut(10));
1157      panel.add(b, "East");
1158      b = Box.createVerticalBox();
1159      b.add(Box.createVerticalStrut(10));
1160      panel.add(b, "North");
1161      b = Box.createVerticalBox();
1162      b.add(Box.createVerticalStrut(10));
1163      panel.add(b, "South");
1164      
1165      panel.add(textPanel, "Center");
1166
1167      tabs.addTab("Photo Info", panel);
1168
1169      /* Camera Info tab
1170         provides text fields with info about the camera
1171         that the photo was taken with
1172      */
1173      panel = new JPanel();
1174      panel.setLayout(new BorderLayout());
1175      textPanel = new JPanel();
1176      textPanel.setLayout(new GridLayout(7,2,5,1));
1177      label = new JLabel("Equipment Maker");
1178      text = new JTextField(10);
1179      text.setText(photoInfo.getEquipmentMaker());
1180      text.setActionCommand("equipmentMaker");
1181      text.addActionListener(this);
1182      text.addCaretListener(this);
1183      textPanel.add(label);
1184      textPanel.add(text);
1185
1186      label = new JLabel("Equipment Model");
1187      text = new JTextField(10);
1188      text.setText(photoInfo.getEquipmentModel());
1189      text.setActionCommand("equipmentModel");
1190      text.addActionListener(this);
1191      text.addCaretListener(this);
1192      textPanel.add(label);
1193      textPanel.add(text);
1194
1195      label = new JLabel("ISO Speed");
1196      text = new JTextField(10);
1197      text.setText(photoInfo.getISOSpeedEquivalent());
1198      text.setActionCommand("isoSpeed");
1199      text.addActionListener(this);
1200      text.addCaretListener(this);
1201      textPanel.add(label);
1202      textPanel.add(text);
1203
1204      label = new JLabel("Max. Aperture Setting");
1205      text = new JTextField(10);
1206      text.setText(photoInfo.getMaximumApertureSetting());
1207      text.setActionCommand("maxAperture");
1208      text.addActionListener(this);
1209      text.addCaretListener(this);
1210      textPanel.add(label);
1211      textPanel.add(text);
1212
1213      label = new JLabel("Lens Focal Length");
1214      text = new JTextField(10);
1215      text.setText(photoInfo.getLensFocalLength());
1216      text.setActionCommand("focalLength");
1217      text.addActionListener(this);
1218      text.addCaretListener(this);
1219      textPanel.add(label);
1220      textPanel.add(text);
1221
1222      label = new JLabel("Lens F Number");
1223      text = new JTextField(10);
1224      text.setText(photoInfo.getLensFNumber());
1225      text.setActionCommand("fNumber");
1226      text.addActionListener(this);
1227      text.addCaretListener(this);
1228      textPanel.add(label);
1229      textPanel.add(text);
1230
1231      label = new JLabel();
1232      textPanel.add(label);
1233
1234      b = Box.createVerticalBox();
1235      b.add(Box.createHorizontalStrut(10));
1236      panel.add(b, "West");
1237      b = Box.createVerticalBox();
1238      b.add(Box.createHorizontalStrut(10));
1239      panel.add(b, "East");
1240      b = Box.createVerticalBox();
1241      b.add(Box.createVerticalStrut(10));
1242      panel.add(b, "North");
1243      b = Box.createVerticalBox();
1244      b.add(Box.createVerticalStrut(10));
1245      panel.add(b, "South");
1246
1247      panel.add(textPanel, "Center");
1248      tabs.addTab("Camera Info", panel);
1249
1250      /* Image Info
1251         Provides text fields with information specific to the
1252         format of the digital photo
1253      */
1254      panel = new JPanel();
1255      panel.setLayout(new BorderLayout());
1256
1257      textPanel = new JPanel();
1258      textPanel.setLayout(new GridLayout(7,2,5,1));
1259      label = new JLabel("Photo URL");
1260      text = new JTextField(10);
1261      text.setText(photoInfo.getURL());
1262      text.setActionCommand("URL");
1263      text.addActionListener(this);
1264      text.addCaretListener(this);
1265      textPanel.add(label);
1266      textPanel.add(text);
1267
1268      textPanel = new JPanel();
1269      textPanel.setLayout(new GridLayout(7,2,5,1));
1270      label = new JLabel("Color Space");
1271      list = new Vector();
1272      list.insertElementAt("sRGB", list.size());
1273      list.insertElementAt("Reserved", list.size());
1274      combo = new JComboBox(list);
1275      if(photoInfo.getColorSpace() != null) {
1276    combo.setSelectedItem(photoInfo.getColorSpace());
1277      }
1278      else {
1279    combo.setSelectedItem(