View Javadoc

1   /*
2    * IconBrowser.java
3    *
4    * Created on March 6, 2001, 4:48 PM
5    */
6   
7   package org.freehep.demo.iconbrowser;
8   
9   import java.awt.*;
10  import javax.swing.border.EmptyBorder;
11  import javax.swing.event.TreeSelectionEvent;
12  import javax.swing.event.TreeSelectionListener;
13  import javax.swing.filechooser.FileFilter;
14  import javax.swing.tree.DefaultMutableTreeNode;
15  import javax.swing.tree.DefaultTreeCellRenderer;
16  import javax.swing.tree.DefaultTreeModel;
17  import javax.swing.tree.TreePath;
18  import org.freehep.application.*;
19  import org.freehep.application.services.FileAccess;
20  import org.freehep.swing.ExtensionFileFilter;
21  import org.freehep.swing.layout.FlowScrollLayout;
22  import org.freehep.swing.popup.HasPopupItems;
23  import java.util.zip.ZipFile;
24  import java.util.zip.ZipInputStream;
25  import javax.swing.*;
26  import java.awt.datatransfer.DataFlavor;
27  import java.awt.datatransfer.Transferable;
28  import java.awt.datatransfer.UnsupportedFlavorException;
29  import java.awt.event.MouseEvent;
30  import java.awt.print.PageFormat;
31  import java.awt.print.Pageable;
32  import java.awt.print.Printable;
33  import java.awt.print.PrinterException;
34  import java.io.IOException;
35  import java.io.InputStream;
36  import java.io.InputStreamReader;
37  import java.io.LineNumberReader;
38  import java.lang.reflect.Field;
39  import java.util.*;
40  import org.freehep.util.commanddispatcher.BooleanCommandState;
41  import org.freehep.util.commanddispatcher.CommandState;
42  import org.freehep.util.images.ImageHandler;
43  
44  
45  /**
46   * A simple GUI based browser for Icon Collections.
47   * @author Tony Johnson (tonyj@slac.stanford.edu)
48   * @version $Id: IconBrowser.java 10506 2007-01-30 22:48:57Z duns $
49   */
50  public class IconBrowser extends Application implements TreeSelectionListener
51  {
52     private JTree tree = new JTree();
53     private IconPanel iconPanel;
54     private JScrollPane scroll = new JScrollPane();
55     private IconMagnifier magnifier = new IconMagnifier();
56     private JSplitPane split2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,new JScrollPane(tree),new JScrollPane(magnifier));
57     private JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,split2,scroll);
58     private boolean showNames;
59     private DefaultMutableTreeNode currentFile;
60     private IconLabel currentIcon;
61     private FileTree fileTree = new FileTree();
62     private String[] builtIn;
63     private ProgressMeter meter = new ProgressMeter(false);
64  
65     /** Creates new IconBrowser */
66     public IconBrowser() throws Exception
67     {
68        super("IconBrowser");
69        add(split);
70  
71        Properties user = getUserProperties();
72        int pos = PropertyUtilities.getInteger(user,"splitPosition",0);
73        if (pos > 0) split.setDividerLocation(pos);
74        pos = PropertyUtilities.getInteger(user,"splitPosition2",0);
75        if (pos > 0) split2.setDividerLocation(pos);
76        showNames = PropertyUtilities.getBoolean(user,"showNames",false);
77        magnifier.setShowGrid(PropertyUtilities.getBoolean(user,"showGrid",true));
78        magnifier.setShowChecks(PropertyUtilities.getBoolean(user,"showChecks",true));
79        magnifier.setMagnification(PropertyUtilities.getInteger(user,"magnification",5));
80  
81        tree.setModel(fileTree);
82        tree.setRootVisible(false);
83        tree.setCellRenderer(new IconTreeRenderer());
84  
85        tree.addTreeSelectionListener(this);
86        scroll.getViewport().setBackground(Color.white);
87        getStatusBar().add(meter);
88     }
89     protected void init()
90     {
91        // Look for built-in archives
92  
93        InputStream in = getClass().getResourceAsStream("/IconBrowser.list");
94        if (in != null)
95        {
96           try
97           {
98              Vector v = new Vector();
99              LineNumberReader reader = new LineNumberReader(new InputStreamReader(in));
100             for (;;)
101             {
102                String line = reader.readLine();
103                if (line == null) break;
104                v.add(line);
105             }
106             reader.close();
107             builtIn = new String[v.size()];
108             v.copyInto(builtIn);
109          }
110          catch (IOException x)
111          {
112          }
113       }
114 
115       boolean atLeastOneFileOpenFailed = false;
116       String[] files = PropertyUtilities.getStringArray(getUserProperties(),"openFiles",null);
117       if (files != null)
118       {
119          for (int i=0; i<files.length; i++)
120          {
121             String file = files[i];
122             setStatusMessage("Scanning "+fileName(file));
123             try
124             {
125                if (file.startsWith("builtin:/"))
126                {
127                   DefaultMutableTreeNode node = new ZipListTree(file.substring(9));
128                   fileTree.addArchive(node);
129                }
130                else
131                {
132                   DefaultMutableTreeNode node = new ZipTree(new ZipFile(files[i]));
133                   fileTree.addArchive(node);
134                }
135             }
136             catch (SecurityException x)
137             {
138                // In case we are in JNLP
139                atLeastOneFileOpenFailed = true;
140             }
141             catch (IOException x)
142             {
143                // Probably the file doesnt exist anymore
144                atLeastOneFileOpenFailed = true;
145             }
146          }
147       }
148       if (atLeastOneFileOpenFailed) return;
149       // restore open tree nodes
150       try
151       {
152          String openPaths = PropertyUtilities.getString(getUserProperties(),"openPaths",null);
153          if (openPaths != null)
154          {
155             StringTokenizer tk = new StringTokenizer(openPaths,",");
156             int[] paths = new int[tk.countTokens()];
157             for (int i=0; i<paths.length; i++) paths[i] = Integer.parseInt(tk.nextToken());
158 
159             Arrays.sort(paths);
160             for (int i=0; i<paths.length; i++)
161             {
162                int row = paths[i];
163                if (row < 0) continue;
164                tree.expandRow(row);
165             }
166          }
167          int selRow = PropertyUtilities.getInteger(getUserProperties(),"selectedRow",-1);
168          if (selRow >= 0) tree.setSelectionRow(selRow);
169       }
170       catch (NumberFormatException x)
171       {
172          // o well, we tried
173       }
174    }
175    public static void main(String[] argv) throws Exception
176    {
177       new IconBrowser().createFrame(argv).setVisible(true);
178    }
179    public void onSaveIcon()
180    {
181       Runnable run = new Runnable()
182       {
183          public void run()
184          {
185             try
186             {
187                SaveAs saveAs = (SaveAs) Class.forName("org.freehep.demo.iconbrowser.SaveAsDialog").newInstance();
188                String name = fileName(currentIcon.getToolTipText());
189                saveAs.showExportDialog(IconBrowser.this,"Save Icon...",currentIcon,name);
190             }
191             catch (Throwable t)
192             {
193                error("Error creating export dialog",t);
194             }
195          }
196       };
197       whenAvailable("graphicsio",run);
198    }
199    public void enableSaveIcon(CommandState state)
200    {
201       state.setEnabled(currentIcon != null);
202    }
203    public void onShowNames(boolean state)
204    {
205       showNames = state;
206       if (iconPanel != null)
207       {
208          iconPanel.showNames(state);
209          iconPanel.revalidate();
210       }
211       getCommandProcessor().setChanged();
212    }
213    public void enableShowNames(BooleanCommandState state)
214    {
215       state.setEnabled(true);
216       state.setSelected(showNames);
217    }
218    public void onShowGrid(boolean state)
219    {
220       magnifier.setShowGrid(state);
221    }
222    public void enableShowGrid(BooleanCommandState state)
223    {
224       state.setEnabled(true);
225       state.setSelected(magnifier.getShowGrid());
226    }
227    public void onShowChecks(boolean state)
228    {
229       magnifier.setShowChecks(state);
230    }
231    public void enableShowChecks(BooleanCommandState state)
232    {
233       state.setEnabled(true);
234       state.setSelected(magnifier.getShowChecks());
235    }
236    public void on2x(boolean state)
237    {
238       if (state) magnifier.setMagnification(2);
239       getCommandProcessor().setChanged();
240    }
241    public void enable2x(BooleanCommandState state)
242    {
243       state.setEnabled(true);
244       state.setSelected(magnifier.getMagnification() == 2);
245    }
246    public void on3x(boolean state)
247    {
248       if (state) magnifier.setMagnification(3);
249       getCommandProcessor().setChanged();
250    }
251    public void enable3x(BooleanCommandState state)
252    {
253       state.setEnabled(true);
254       state.setSelected(magnifier.getMagnification() == 3);
255    }
256    public void on5x(boolean state)
257    {
258       if (state) magnifier.setMagnification(5);
259       getCommandProcessor().setChanged();
260    }
261    public void enable5x(BooleanCommandState state)
262    {
263       state.setEnabled(true);
264       state.setSelected(magnifier.getMagnification() == 5);
265    }
266    public void on10x(boolean state)
267    {
268       if (state) magnifier.setMagnification(10);
269        getCommandProcessor().setChanged();
270    }
271    public void enable10x(BooleanCommandState state)
272    {
273       state.setEnabled(true);
274       state.setSelected(magnifier.getMagnification() == 10);
275    }
276    public void onCopyIcon()
277    {
278       IconSelection t = new IconSelection(currentIcon);
279       getServiceManager().setClipboardContents(t);
280    }
281    public void enableCopyIcon(CommandState state)
282    {
283       state.setEnabled(currentIcon != null);
284    }
285    public void onLicense()
286    {
287       showHelpTopic("License");
288    }
289    public void onSearch()
290    {
291       String search = RecentItemTextField.showInputDialog(this,"Search for: ","Icon Search");
292       if (search != null)
293       {
294          search = search.toLowerCase();
295          IconPanel iconPanel = new IconPanel();
296          DefaultMutableTreeNode root = (DefaultMutableTreeNode) fileTree.getRoot();
297          Enumeration e = root.depthFirstEnumeration();
298          while (e.hasMoreElements())
299          {
300             DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement();
301             if (node.getUserObject() instanceof IconDirectory)
302             {
303                IconDirectory id = (IconDirectory) node.getUserObject();
304                for (int i=0; i<id.getNEntries(); i++)
305                {
306                   String name = id.getEntryName(i).toLowerCase();
307 
308                   if (name.indexOf(search) >= 0)
309                   {
310                      DefaultMutableTreeNode zipNode = (DefaultMutableTreeNode) node.getPath()[1];
311                      Icon icon = id.getEntryIcon(i);
312                      iconPanel.add(new IconLabel(id.getEntryName(i),icon,showNames));
313                   }
314                }
315             }
316          }
317          if (iconPanel.getComponentCount() == 0)
318          {
319             error("No matches for "+search);
320          }
321          else
322          {
323             tree.clearSelection();
324             setIconPanel(iconPanel);
325          }
326       }
327    }
328    public void onOpen()
329    {
330       FileFilter[] filters = { new ExtensionFileFilter(new String[]{"jar","zip"},"Image Icon Libraries") };
331       FileAccess file = getServiceManager().openFileDialog(filters,null,"openFile");
332       try
333       {
334          if (file != null)
335          {
336             setStatusMessage("Scanning "+file.getName());
337             try
338             {
339                DefaultMutableTreeNode node = new ZipTree(new ZipFile(file.getFile()));
340                fileTree.addArchive(node);
341             }
342             catch (SecurityException x)
343             {
344                DefaultMutableTreeNode node = new ZipInputStreamTree(file.getName(),new ZipInputStream(file.getInputStream()));
345                fileTree.addArchive(node);
346             }
347          }
348       }
349       catch (IOException x)
350       {
351          error("Error opening file",x);
352       }
353    }
354    public void onOpenFromClassPath() throws Exception
355    {
356       String sel = (String) JOptionPane.showInputDialog(this,
357       "Select Icon Collection","Open Icon Collection",JOptionPane.QUESTION_MESSAGE,
358       null,builtIn,builtIn[0]);
359       if (sel != null)
360       {
361          setStatusMessage("Scanning "+sel);
362          fileTree.addArchive(new ZipListTree(sel));
363          getCommandProcessor().setChanged();
364       }
365    }
366    public void enableOpenFromClassPath(CommandState state)
367    {
368       state.setEnabled(builtIn != null && builtIn.length > 0);
369    }
370    public void onClose()
371    {
372       DefaultMutableTreeNode old = currentFile;
373       currentFile = null;
374       fileTree.removeNodeFromParent(old);
375       getCommandProcessor().setChanged();
376       IconArchive archive = (IconArchive) old.getUserObject();
377       archive.close();
378    }
379    public void enableClose(CommandState state)
380    {
381       state.setEnabled(currentFile!=null);
382    }
383    public void onPrintPreview()
384    {
385       Pageable pageable = iconPanel.getPageable(getServiceManager().getDefaultPage());
386       PrintPreview pp =  createPrintPreview();
387       pp.setPageable(pageable);
388       showDialog(pp.createDialog(this),"PrintPreview");
389    }
390    public void enablePrintPreview(CommandState state)
391    {
392       state.setEnabled(iconPanel != null && iconPanel.getComponentCount()>0);
393    }
394    public void onPrint()
395    {
396       Pageable pageable = iconPanel.getPageable(getServiceManager().getDefaultPage());
397       getServiceManager().print(pageable);
398    }
399    public void enablePrint(CommandState state)
400    {
401       state.setEnabled(iconPanel != null && iconPanel.getComponentCount()>0);
402    }
403    void setCurrentIcon(IconLabel label)
404    {
405       magnifier.setIcon(label.getIcon());
406       currentIcon = label;
407       getCommandProcessor().setChanged();
408    }
409    void setIconPanel(IconPanel p)
410    {
411       iconPanel = p;
412       scroll.setViewportView(p);
413       p.validate();
414       getCommandProcessor().setChanged();
415    }
416    public void valueChanged(TreeSelectionEvent event)
417    {
418       if (!event.isAddedPath())
419       {
420          currentFile = null;
421          setIconPanel(new IconPanel());
422          return;
423       }
424       TreePath path = event.getPath();
425       currentFile = (DefaultMutableTreeNode) path.getPathComponent(1);
426       getCommandProcessor().setChanged();
427       DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
428       if (node.getUserObject() instanceof IconDirectory)
429       {
430          final IconDirectory dir = (IconDirectory) node.getUserObject();
431          final String name = dir.getName();
432 
433          final BoundedRangeModel bdr = new DefaultBoundedRangeModel(0,0,0,dir.getNEntries());
434          meter.setModel(bdr);
435 
436          Thread t = new Thread()
437          {
438             public void run()
439             {
440                final IconPanel iconPanel = new IconPanel();
441                for (int n=0, i=0; i < dir.getNEntries(); i++)
442                {
443                   Icon icon = dir.getEntryIcon(i);
444                   iconPanel.add(new IconLabel(dir.getEntryName(i),icon,showNames));
445                   bdr.setValue(++n);
446                }
447                SwingUtilities.invokeLater(new Runnable()
448                {
449                   public void run()
450                   {
451                      setIconPanel(iconPanel);
452                   }
453                });
454             }
455          };
456          t.start();
457       }
458    }
459 
460    protected void saveUserProperties()
461    {
462       Properties user = getUserProperties();
463       PropertyUtilities.setBoolean(user,"showNames",showNames);
464       PropertyUtilities.setInteger(user,"splitPosition",split.getDividerLocation());
465       PropertyUtilities.setInteger(user,"splitPosition2",split2.getDividerLocation());
466       PropertyUtilities.setBoolean(user,"showGrid",magnifier.getShowGrid());
467       PropertyUtilities.setBoolean(user,"showChecks",magnifier.getShowChecks());
468       PropertyUtilities.setInteger(user,"magnification",magnifier.getMagnification());
469       // Save any open files
470       DefaultMutableTreeNode root = (DefaultMutableTreeNode) fileTree.getRoot();
471       String[] files = new String[root.getChildCount()];
472       for (int i=0; i<files.length;i++)
473       {
474          DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
475          files[i] = ((IconDirectory) child.getUserObject()).getName();
476       }
477       PropertyUtilities.setStringArray(user,"openFiles",files);
478 
479       // Remember which nodes of the tree were open
480       StringBuffer openPaths = new StringBuffer();
481       Enumeration e = root.depthFirstEnumeration();
482       while (e.hasMoreElements())
483       {
484          DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement();
485          TreePath path = new TreePath(node.getPath());
486          if (tree.isExpanded(path))
487          {
488             if (openPaths.length()>0) openPaths.append(',');
489             openPaths.append(tree.getRowForPath(path));
490          }
491       }
492       user.setProperty("openPaths",openPaths.toString());
493       // Finally save the open folder, if any
494       int[] selRows = tree.getSelectionRows();
495       int selRow = selRows != null ? selRows[0] : -1;
496       PropertyUtilities.setInteger(user,"selectedRow",selRow);
497       super.saveUserProperties();
498    }
499    private class FileTree extends DefaultTreeModel
500    {
501       FileTree()
502       {
503          super(new DefaultMutableTreeNode("root"));
504       }
505       void addArchive(DefaultMutableTreeNode archive)
506       {
507          DefaultMutableTreeNode root = (DefaultMutableTreeNode) getRoot();
508          fileTree.insertNodeInto(archive,root,root.getChildCount());
509          tree.expandPath(new TreePath(new Object[]
510          {root,archive}));
511       }
512    }
513    /**
514     * returns the directory part of fullName, including the trailing slash
515     */
516    static String dirName(String fullName)
517    {
518       int l = fullName.length();
519       if (fullName.endsWith("/")) l--;
520       int pos = fullName.lastIndexOf('/',l-1);
521       if (pos < 0) return null;
522       else return fullName.substring(0,pos+1);
523    }
524    /**
525     * returns the file name, minus the directory
526     */
527    static String fileName(String fullName,String separator)
528    {
529       int l = fullName.length();
530       if (fullName.endsWith(separator)) l--;
531       int pos = fullName.lastIndexOf(separator,l-1);
532       if (pos < 0) return fullName.substring(0,l);
533       return fullName.substring(pos+1,l);
534    }
535    static String fileName(String fullName)
536    {
537       return fileName(fullName,"/");
538    }
539    public static class IconSelection implements Transferable
540    {
541       private DataFlavor imageFlavor;
542       private DataFlavor stringFlavor;
543       private Vector supportedFlavors = new Vector();
544       private IconLabel icon;
545 
546       public IconSelection(IconLabel icon)
547       {
548          imageFlavor = getFlavor("imageFlavor");
549          stringFlavor = getFlavor("stringFlavor");
550          if (imageFlavor != null) supportedFlavors.add(imageFlavor);
551          if (stringFlavor != null) supportedFlavors.add(stringFlavor);
552          this.icon = icon;
553       }
554       private DataFlavor getFlavor(String flavor)
555       {
556          try
557          {
558             // For JDK 1.3 compatibility
559             Class k = DataFlavor.class;
560             Field field = k.getField(flavor);
561             return (DataFlavor) field.get(null);
562          }
563          catch (Throwable t)
564          {
565             return null;
566          }
567       }
568       public DataFlavor [] getTransferDataFlavors()
569       {
570          DataFlavor[] result = new DataFlavor[supportedFlavors.size()];
571          supportedFlavors.toArray(result);
572          return result;
573       }
574       public boolean isDataFlavorSupported(DataFlavor parFlavor)
575       {
576          return supportedFlavors.contains(parFlavor);
577       }
578       public Object getTransferData(DataFlavor parFlavor) throws UnsupportedFlavorException
579       {
580          if      (parFlavor.equals(imageFlavor)) return ((ImageIcon) icon.getIcon()).getImage();
581          else if (parFlavor.equals(stringFlavor)) return icon.getToolTipText();
582          else throw new UnsupportedFlavorException(imageFlavor);
583       }
584    }
585    private class IconPanel extends JPanel implements Scrollable, HasPopupItems
586    {
587       IconPanel()
588       {
589          FlowScrollLayout l = new FlowScrollLayout(scroll);
590          l.setHgap(0);
591          l.setVgap(0);
592          setLayout(l);
593          setBackground(Color.white);
594       }
595       public Dimension getPreferredScrollableViewportSize()
596       {
597          return getPreferredSize();
598       }
599       public int getScrollableUnitIncrement(Rectangle visibleRect,
600       int orientation,
601       int direction)
602       {
603          return 1;
604       }
605       public int getScrollableBlockIncrement(Rectangle visibleRect,
606       int orientation,
607       int direction)
608       {
609          return 10;
610       }
611       public boolean getScrollableTracksViewportWidth()
612       {
613          return true;
614       }
615       public boolean getScrollableTracksViewportHeight()
616       {
617          return false;
618       }
619       void showNames(boolean state)
620       {
621          Component[] comps = getComponents();
622          for (int i=0; i<comps.length; i++)
623          {
624             IconLabel label = (IconLabel) comps[i];
625             label.setShowText(state);
626          }
627       }
628       public JPopupMenu modifyPopupMenu(JPopupMenu menu, Component source, Point point)
629       {
630          if (source != this) return menu;
631          return getXMLMenuBuilder().getPopupMenu("panelMenu");
632       }
633 
634       Pageable getPageable(final PageFormat pf)
635       {
636          // Figure out which is the first icon on each line, and how many pages
637          // we need.
638 
639          int xsize = (int) pf.getImageableWidth();
640          int ysize = (int) pf.getImageableHeight();
641          final Vector pages = new Vector();
642          final Vector lines = new Vector();
643          pages.addElement(new Integer(0));
644          lines.addElement(new Integer(0));
645          int maxHeight = 0;
646          int totWidth = 0;
647          int totHeight = 0;
648 
649          int n = getComponentCount();
650          for (int i=0; i<n; i++)
651          {
652             IconLabel l = (IconLabel) getComponent(i);
653             int height = l.getHeight();
654             int width = l.getWidth();
655             if (totWidth + width > xsize) // new line?
656             {
657                lines.addElement(new Integer(i));
658                totHeight += maxHeight;
659                maxHeight = 0;
660                totWidth = width;
661 
662                if (totHeight > ysize)
663                {
664                   pages.addElement(new Integer(lines.size()));
665                   totHeight = maxHeight;
666                }
667             }
668             else
669             {
670                totWidth += width;
671                if (height > maxHeight) maxHeight = height;
672             }
673          }
674          final Printable printable = new Printable()
675          {
676             public int print(Graphics graphics,PageFormat pageFormat,int pageIndex) throws PrinterException
677             {
678                Graphics2D g2 = (Graphics2D) graphics;
679                g2.translate(pageFormat.getImageableX(),pageFormat.getImageableY());
680                if (pageIndex >= pages.size()) return NO_SUCH_PAGE;
681                int firstLine = ((Integer) pages.elementAt(pageIndex)).intValue();
682                int lastLine = pageIndex+1 == pages.size() ? lines.size() : ((Integer) pages.elementAt(pageIndex+1)).intValue();
683                for (int l = firstLine; l < lastLine; l++)
684                {
685                   int firstLabel = ((Integer) lines.elementAt(l)).intValue();
686                   int lastLabel = l+1 == lines.size() ? getComponentCount() : ((Integer) lines.elementAt(l+1)).intValue();
687                   double maxHeight = 0;
688                   double offset = 0;
689                   for (int c = firstLabel; c<lastLabel; c++)
690                   {
691                      IconLabel label = (IconLabel) getComponent(c);
692                      label.print(g2);
693                      double w = label.getWidth();
694                      double h = label.getHeight();
695                      offset += w;
696                      if (h > maxHeight) maxHeight = h;
697                      g2.translate(w,0);
698                   }
699                   g2.translate(-offset,maxHeight);
700                }
701                return PAGE_EXISTS;
702             }
703          };
704          return new Pageable()
705          {
706             public Printable getPrintable(int page)
707             {
708                return printable;
709             }
710             public PageFormat getPageFormat(int page)
711             {
712                return pf;
713             }
714             public int getNumberOfPages()
715             {
716                return pages.size();
717             }
718          };
719 
720       }     
721    }
722    private class IconLabel extends JLabel implements HasPopupItems
723    {
724       IconLabel(String name, Icon icon, boolean showText)
725       {
726          super(icon);
727          setToolTipText(name);
728          setHorizontalTextPosition(CENTER);
729          setVerticalTextPosition(BOTTOM);
730          setBorder(new EmptyBorder(3,3,3,3));
731          enableEvents(AWTEvent.MOUSE_EVENT_MASK);
732          setShowText(showText);
733       }
734       void setShowText(boolean show)
735       {
736          if (show) setText(fileName(getToolTipText()));
737          else setText(null);
738       }
739       protected void processMouseEvent(MouseEvent e)
740       {
741          int id = e.getID();
742          if (id == e.MOUSE_ENTERED)
743          {
744             Icon icon  = getIcon();
745             setStatusMessage(getToolTipText()+" ("+icon.getIconWidth()+"x"+icon.getIconHeight()+")");
746             paintBorder = true;
747             repaint();
748          }
749          else if (id == e.MOUSE_EXITED)
750          {
751             paintBorder = false;
752             repaint();
753          }
754          else if (id == e.MOUSE_PRESSED)
755          {
756             if (currentIcon != this)
757             {
758                JLabel oldIcon = currentIcon;
759                setCurrentIcon(this);
760                if (oldIcon != null) oldIcon.repaint();
761                repaint();
762             }
763          }
764          super.processMouseEvent(e);
765       }
766       protected void printBorder(Graphics g)
767       {
768          // no border when printing
769       }
770       protected void paintBorder(Graphics g)
771       {
772          if (paintBorder)
773          {
774             g.setColor(Color.red);
775             g.drawRect(2,2,getWidth()-5,getHeight()-5);
776          }
777          if (currentIcon == this)
778          {
779             g.setColor(Color.blue);
780             g.drawRect(1,1,getWidth()-3,getHeight()-3);
781             g.drawRect(0,0,getWidth()-1,getHeight()-1);
782          }
783       }
784       public JPopupMenu modifyPopupMenu(JPopupMenu menu,Component source, Point p)
785       {
786          return getXMLMenuBuilder().getPopupMenu("labelMenu");
787       }
788       
789       private boolean paintBorder;
790    }
791    private class IconTreeRenderer extends DefaultTreeCellRenderer
792    {
793       public Component getTreeCellRendererComponent(JTree tree,Object value,boolean sel,boolean expanded,boolean leaf,int row,boolean hasFocus)
794       {
795          super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
796          if (value instanceof DefaultMutableTreeNode)
797          {
798             DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
799             Object user = node.getUserObject();
800             if (user instanceof IconDirectory)
801             {
802                IconDirectory id = (IconDirectory) user;
803                if (id instanceof IconArchive) setIcon(zipIcon);
804                else if (expanded) setIcon(openFolderIcon);
805                else if (sel && id.getNEntries() > 0) setIcon(openFolderIcon);
806                else setIcon(closedFolderIcon);
807             }
808          }
809          return this;
810       }
811    }
812    private class IconMagnifier extends JPanel implements HasPopupItems
813    {
814       private ImageIcon icon;
815       private boolean showGrid = true;
816       private boolean showChecks = true;
817       private int mag = 5;
818       IconMagnifier()
819       {
820          setBackground(Color.white);
821       }
822       void setIcon(Icon icon)
823       {
824          this.icon = (ImageIcon) icon;
825          if (icon != null)
826          {
827             setPreferredSize(new Dimension(mag*icon.getIconWidth(),mag*icon.getIconHeight()));
828             revalidate();
829          }
830          repaint();
831       }
832       void setShowGrid(boolean value)
833       {
834          showGrid = value;
835          repaint();
836       }
837       boolean getShowGrid()
838       {
839          return showGrid;
840       }
841       void setShowChecks(boolean value)
842       {
843          showChecks = value;
844          repaint();
845       }
846       boolean getShowChecks()
847       {
848          return showChecks;
849       }
850       int getMagnification()
851       {
852          return mag;
853       }
854       void setMagnification(int value)
855       {
856          mag = value;
857          if (icon != null)
858          {
859             setPreferredSize(new Dimension(mag*icon.getIconWidth(),mag*icon.getIconHeight()));
860             revalidate();
861          }
862          repaint();
863       }
864       public void paintComponent(Graphics g)
865       {
866          super.paintComponent(g);
867          if (icon != null)
868          {
869             if (showChecks)
870             {
871                for (int i=0; i<icon.getIconWidth(); i++)
872                {
873                   for (int j=0; j<icon.getIconHeight(); j++)
874                   {
875                      g.setColor((i+j)%2 == 0 ? Color.lightGray : Color.darkGray);
876                      int x = i*mag;
877                      int y = j*mag;
878                      g.fillRect(x,y,mag,mag);
879                   }
880                }
881             }
882 
883             g.drawImage(icon.getImage(),0,0,mag*icon.getIconWidth(),mag*icon.getIconHeight(),this);
884 
885             if (showGrid)
886             {
887                g.setColor(Color.gray);
888                for (int i=0; i<=icon.getIconWidth(); i++)
889                {
890                   int x = i*mag;
891                   g.drawLine(x,0,x,mag*icon.getIconHeight());
892                }
893                for (int i=0; i<=icon.getIconHeight(); i++)
894                {
895                   int y = i*mag;
896                   g.drawLine(0,y,mag*icon.getIconWidth(),y);
897                }
898             }
899          }
900       }
901 
902       public JPopupMenu modifyPopupMenu(JPopupMenu menu, Component source, Point p)
903       {
904          return getXMLMenuBuilder().getPopupMenu("magnifierMenu");
905       }
906       
907       
908    }
909    private final static Icon zipIcon = ImageHandler.getIcon(IconBrowser.class.getResource("/org/javalobby/icons/20x20/Package.gif"));
910    private final static Icon openFolderIcon = ImageHandler.getIcon(IconBrowser.class.getResource("/org/javalobby/icons/20x20/OpenProject.gif"));
911    private final static Icon closedFolderIcon = ImageHandler.getIcon(IconBrowser.class.getResource("/org/javalobby/icons/20x20/Project.gif"));
912 
913  }
914 interface SaveAs
915 {
916    public void showExportDialog(Component parent, String title, Component target, String name);
917 }