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(