001/*
002 * Version 0.70 01/04/2002
003 *
004 * Visit my url for update: http://www.geocities.com/beapetrovicova/
005 * 
006 * jFtp was developed by Bea Petrovicova <beapetrovicova@yahoo.com>.
007 * The design and implementation of jFtp are available for royalty-free 
008 * adoption and use. This software is provided 'as is' without any 
009 * guarantees. Copyright is retained by Bea Petrovicova. Redistribution 
010 * of any part of jFtp or any derivative works must include this notice.
011 * 
012 */
013
014package cz.dhl.swing;
015
016import cz.dhl.io.CoFile;
017import cz.dhl.io.CoSort;
018import java.awt.Component;
019import java.awt.Graphics;
020import java.awt.event.ActionEvent;
021import java.awt.event.ActionListener;
022import java.awt.event.ItemEvent;
023import java.awt.event.ItemListener;
024import java.util.Vector;
025import javax.swing.AbstractListModel;
026import javax.swing.ComboBoxModel;
027import javax.swing.DefaultComboBoxModel;
028import javax.swing.DefaultListCellRenderer;
029import javax.swing.Icon;
030import javax.swing.JList;
031import javax.swing.JComboBox;
032import javax.swing.UIManager;
033
034/** 
035 * Swing Directory Selector Combo Box Component.<BR><BR>
036 *  <IMG SRC="JCoDirComboBox.gif"><BR><BR>
037 *
038 * <P><I>To listen for dir selection events:</I><BR>
039 * <CODE>
040 * dirChoice.setDirActionListener(new ActionListener()<BR>
041 * {&nbsp;&nbsp;public void actionPerformed(ActionEvent e)<BR>
042 * &nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;myDirSelectHandler(); } } ); 
043 * </CODE></P>
044 * 
045 * @Version 0.70 01/04/2002
046 * @author Bea Petrovicova <beapetrovicova@yahoo.com>
047 * @see java.io.File
048 */
049public class JCoDirComboBox extends JComboBox
050{  private Icon hardDriveIcon = null;
051   private Icon directoryIcon = null;
052
053   private Vector roots = null; 
054   private CoFile dirs[] = new CoFile[0]; 
055   private CoFile dir = null; CoFile sel = null;
056
057   private ActionListener listener = null;
058
059   private void installIcons() 
060   {  if(hardDriveIcon==null)
061      {  hardDriveIcon = UIManager.getIcon("FileView.hardDriveIcon"); }
062      if(directoryIcon==null)
063      {  directoryIcon = UIManager.getIcon("FileView.directoryIcon"); } }
064   
065   private class DirRenderer extends DefaultListCellRenderer
066   {  IndentIcon indent = new IndentIcon();
067      public Component getListCellRendererComponent(JList list, Object value,
068         int index, boolean isSelected, boolean cellHasFocus)
069      {  super.getListCellRendererComponent
070               (list, value, index, isSelected, cellHasFocus);
071         if(value instanceof CoFile) 
072         {  CoFile d = (CoFile)value;
073            indent.depth = d.getPathDepth();
074            installIcons();
075            if(indent.depth>0)
076               indent.icon = directoryIcon;
077            else indent.icon = hardDriveIcon;
078            setIcon(indent);
079            if(indent.depth>0)
080               setText(d.getName());
081            else setText(d.getHost()+d.toString()); 
082         } return this;
083      }
084   };
085
086   private final static int space = 10;
087   private class IndentIcon implements Icon 
088   {  Icon icon = null; int depth = 0;
089      public void paintIcon(Component c,Graphics g,int x,int y)
090      {  if(icon!=null) icon.paintIcon(c, g, x+depth*space, y); }
091      public int getIconWidth()
092      {  return depth*space + (icon!=null?icon.getIconWidth():0); }
093      public int getIconHeight()
094      { return (icon!=null?icon.getIconHeight():1); }
095   } 
096
097   private class DirModel 
098      extends AbstractListModel 
099      implements ComboBoxModel 
100   {  public void update()
101      {  fireContentsChanged(this,0, dirs.length-1); }
102      public int getSize()
103      {  return dirs.length; }
104      public Object getElementAt(int index)
105      {  return dirs[index]; }
106      public void setSelectedItem(Object anItem)
107      {  sel = (CoFile)anItem;
108         if(listener!=null)
109            listener.actionPerformed(new ActionEvent
110               (this,ActionEvent.ACTION_PERFORMED,sel.toString()));
111         fireContentsChanged(this, -1, -1); 
112      }
113      public Object getSelectedItem()
114      {  return sel; }
115   };
116
117   public JCoDirComboBox() 
118   {  setModel(new DirModel()); 
119      setRenderer(new DirRenderer()); }
120
121   /** Sets an ActionListener. The listener will receive 
122    * an action event the user finishes making a dir selection. */
123   public void setDirActionListener(ActionListener listener)
124   {  this.listener=listener; }
125
126   /** Gets directory denoted by this component.
127    * @return directory denoted by component or null */
128   public CoFile getDir() { return dir; }
129
130   /** Sets directory to be denoted by this component.
131    * @parameter dir to be denoted by component or null */
132   public void setDir(final CoFile dir) 
133   {  this.dir = dir; this.sel = dir;
134      if(dir!=null)
135      {  /* Setup Roots. */
136         if(roots==null)
137         {  roots = new Vector();
138            CoFile[] newroots = dir.listCoRoots();
139            for(int i = 0; i < newroots.length; i++)
140               roots.addElement(newroots[i]); } 
141         /* Setup Order Roots & Dirs. */
142         Vector newdirs = (Vector)roots.clone();
143         int n=dir.getPathDepth();
144         for(int i=1;i<n;i++)
145            newdirs.addElement(dir.getPathFragment(i));
146         if(n>=1) newdirs.addElement(dir);
147         dirs = (CoFile[])newdirs.toArray(new CoFile[newdirs.size()]);
148         dirs = CoSort.listOrder(dirs,CoSort.ORDER_BY_PATH);
149      } else { dirs = new CoFile[0]; }
150      ((DirModel)getModel()).update();
151      setEnabled(dirs.length>0);
152   }
153
154   /** Gets directory denoted by (user) selection. 
155    * @return directory denoted by (user) selection or null */
156   public CoFile getSelectedDir()
157   {  return sel; }
158}