Source for javax.swing.plaf.metal.MetalFileChooserUI

   1: /* MetalFileChooserUI.java --
   2:    Copyright (C) 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing.plaf.metal;
  40: 
  41: import java.awt.Component;
  42: import java.awt.event.ActionEvent;
  43: import java.beans.PropertyChangeEvent;
  44: import java.beans.PropertyChangeListener;
  45: import java.io.File;
  46: import java.util.List;
  47: 
  48: import javax.swing.AbstractAction;
  49: import javax.swing.AbstractListModel;
  50: import javax.swing.ComboBoxModel;
  51: import javax.swing.DefaultListCellRenderer;
  52: import javax.swing.JComponent;
  53: import javax.swing.JFileChooser;
  54: import javax.swing.JList;
  55: import javax.swing.UIManager;
  56: import javax.swing.filechooser.FileFilter;
  57: import javax.swing.filechooser.FileSystemView;
  58: import javax.swing.filechooser.FileView;
  59: import javax.swing.plaf.ComponentUI;
  60: import javax.swing.plaf.basic.BasicFileChooserUI;
  61: 
  62: 
  63: /**
  64:  * A UI delegate for the {@link JFileChooser} component.  This class is only
  65:  * partially implemented and is not usable yet.
  66:  */
  67: public class MetalFileChooserUI extends BasicFileChooserUI
  68: {
  69:   /** 
  70:    * A combo box model containing the selected directory and all its parent
  71:    * directories.
  72:    */
  73:   protected class DirectoryComboBoxModel extends AbstractListModel
  74:     implements ComboBoxModel
  75:   {
  76:     /** Storage for the items in the model. */
  77:     private List items;
  78:     
  79:     /** The index of the selected item. */
  80:     private int selectedIndex;
  81:     
  82:     /**
  83:      * Creates a new model.
  84:      */
  85:     public DirectoryComboBoxModel() 
  86:     {
  87:       items = new java.util.ArrayList();
  88:       selectedIndex = -1;
  89:     }
  90:     
  91:     /**
  92:      * Returns the number of items in the model.
  93:      * 
  94:      * @return The number of items in the model.
  95:      */
  96:     public int getSize()
  97:     {
  98:       return items.size();
  99:     }
 100:     
 101:     /**
 102:      * Returns the item at the specified index.
 103:      * 
 104:      * @param index  the item index.
 105:      * 
 106:      * @return The item.
 107:      */
 108:     public Object getElementAt(int index)
 109:     {
 110:       return items.get(index);
 111:     }
 112:     
 113:     /**
 114:      * Returns the depth of the item at the given <code>index</code>.
 115:      * 
 116:      * @param index  the item index.
 117:      * 
 118:      * @return The depth.
 119:      */
 120:     public int getDepth(int index)
 121:     {
 122:       return Math.max(index, 0);
 123:     }
 124: 
 125:     /**
 126:      * Returns the selected item, or <code>null</code> if no item is selected.
 127:      * 
 128:      * @return The selected item, or <code>null</code>.
 129:      */
 130:     public Object getSelectedItem()
 131:     {
 132:       if (selectedIndex >= 0) 
 133:         return items.get(selectedIndex);
 134:       else
 135:         return null;
 136:     }
 137:     
 138:     /**
 139:      * Sets the selected item.  This clears all the directories from the
 140:      * existing list, and repopulates it with the new selected directory
 141:      * and all its parent directories.
 142:      * 
 143:      * @param selectedDirectory  the selected directory.
 144:      */
 145:     public void setSelectedItem(Object selectedDirectory)
 146:     {
 147:       items.clear();
 148:       FileSystemView fsv = getFileChooser().getFileSystemView();
 149:       File parent = (File) selectedDirectory;
 150:       while (parent != null)
 151:         {
 152:           items.add(0, parent);
 153:           parent = fsv.getParentDirectory(parent);
 154:         }
 155:       selectedIndex = items.indexOf(selectedDirectory);
 156:       fireContentsChanged(this, 0, items.size() - 1);
 157:     }
 158:     
 159:   }
 160: 
 161:   /**
 162:    * Handles changes to the selection in the directory combo box.
 163:    */
 164:   protected class DirectoryComboBoxAction extends AbstractAction
 165:   {
 166:     /**
 167:      * Creates a new action.
 168:      */
 169:     protected DirectoryComboBoxAction()
 170:     {
 171:       // Nothing to do here.
 172:     }
 173:     
 174:     /**
 175:      * Handles the action event.
 176:      * 
 177:      * @param e  the event.
 178:      */
 179:     public void actionPerformed(ActionEvent e)
 180:     {
 181:       JFileChooser fc = getFileChooser();
 182:       fc.setCurrentDirectory((File) directoryModel.getSelectedItem());
 183:     }
 184:   }
 185: 
 186:   /**
 187:    * A renderer for the files and directories in the file chooser.
 188:    */
 189:   protected class FileRenderer extends DefaultListCellRenderer
 190:   {
 191:     
 192:     /**
 193:      * Creates a new renderer.
 194:      */
 195:     protected FileRenderer()
 196:     {
 197:       // Nothing to do here.
 198:     }
 199:     
 200:     /**
 201:      * Returns a component that can render the specified value.
 202:      * 
 203:      * @param list  the list.
 204:      * @param value  the value (a {@link File}).
 205:      * @param index  the index.
 206:      * @param isSelected  is the item selected?
 207:      * @param cellHasFocus  does the item have the focus?
 208:      * 
 209:      * @return The renderer.
 210:      */
 211:     public Component getListCellRendererComponent(JList list, Object value,
 212:         int index, boolean isSelected, boolean cellHasFocus)
 213:     {
 214:       FileView v = getFileView(getFileChooser());
 215:       File f = (File) value;
 216:       setText(v.getName(f));
 217:       setIcon(v.getIcon(f));
 218:       if (isSelected)
 219:         {
 220:           setBackground(list.getSelectionBackground());
 221:           setForeground(list.getSelectionForeground());
 222:         }
 223:       else
 224:         {
 225:           setBackground(list.getBackground());
 226:           setForeground(list.getForeground());
 227:         }
 228: 
 229:       setEnabled(list.isEnabled());
 230:       setFont(list.getFont());
 231: 
 232:       if (cellHasFocus)
 233:         setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
 234:       else
 235:         setBorder(noFocusBorder);
 236:       return this;
 237:     }
 238:   }
 239: 
 240:   /**
 241:    * A combo box model for the file selection filters.
 242:    */
 243:   protected class FilterComboBoxModel
 244:     extends AbstractListModel
 245:     implements ComboBoxModel, PropertyChangeListener
 246:   {
 247: 
 248:     /** Storage for the filters in the model. */
 249:     protected FileFilter[] filters;
 250: 
 251:     /** The index of the selected file filter. */
 252:     private int selectedIndex;
 253:     
 254:     /**
 255:      * Creates a new model.
 256:      */
 257:     protected FilterComboBoxModel()
 258:     {
 259:       filters = new FileFilter[1];
 260:       filters[0] = getAcceptAllFileFilter(getFileChooser());
 261:       selectedIndex = 0;
 262:     }
 263:     
 264:     /**
 265:      * Handles property changes.
 266:      * 
 267:      * @param e  the property change event.
 268:      */
 269:     public void propertyChange(PropertyChangeEvent e)
 270:     {
 271:       if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
 272:         {
 273:           selectedIndex = -1;
 274:           FileFilter selected = (FileFilter) e.getNewValue();
 275:           for (int i = 0; i < filters.length; i++)
 276:             if (filters[i].equals(selected))
 277:               selectedIndex = i;
 278:           fireContentsChanged(this, -1, -1);
 279:         }
 280:       else if (e.getPropertyName().equals(
 281:               JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
 282:         {
 283:           // repopulate list
 284:           JFileChooser fc = getFileChooser();
 285:           FileFilter[] choosableFilters = fc.getChoosableFileFilters();
 286:           filters = choosableFilters;
 287:           fireContentsChanged(this, 0, filters.length);
 288:         }
 289:     }
 290:     
 291:     /**
 292:      * Sets the selected filter.
 293:      * 
 294:      * @param filter  the filter.
 295:      */
 296:     public void setSelectedItem(Object filter)
 297:     {
 298:       // change the filter in the file chooser and let the property change
 299:       // event trigger the change to the selected item
 300:       getFileChooser().setFileFilter((FileFilter) filter);
 301:     }
 302:     
 303:     /**
 304:      * Returns the selected file filter.
 305:      * 
 306:      * @return The selected file filter.
 307:      */
 308:     public Object getSelectedItem()
 309:     {
 310:       if (selectedIndex >= 0) 
 311:         return filters[selectedIndex];
 312:       return null;
 313:     }
 314:     
 315:     /**
 316:      * Returns the number of items in the model.
 317:      * 
 318:      * @return The number of items in the model.
 319:      */
 320:     public int getSize()
 321:     {
 322:       return filters.length;
 323:     }
 324:     
 325:     /**
 326:      * Returns the item at the specified index.
 327:      * 
 328:      * @param index  the item index.
 329:      * 
 330:      * @return The item at the specified index.
 331:      */
 332:     public Object getElementAt(int index)
 333:     {
 334:       return filters[index];
 335:     }
 336:     
 337:   }
 338: 
 339:   /**
 340:    * A renderer for the items in the file filter combo box.
 341:    */
 342:   public class FilterComboBoxRenderer extends DefaultListCellRenderer
 343:   {
 344:     /**
 345:      * Creates a new renderer.
 346:      */
 347:     public FilterComboBoxRenderer()
 348:     {
 349:       // Nothing to do here.
 350:     }
 351:     
 352:     /**
 353:      * Returns a component that can be used to paint the given value within 
 354:      * the list.
 355:      * 
 356:      * @param list  the list.
 357:      * @param value  the value (a {@link FileFilter}).
 358:      * @param index  the item index.
 359:      * @param isSelected  is the item selected?
 360:      * @param cellHasFocus  does the list cell have focus?
 361:      * 
 362:      * @return A component.
 363:      */
 364:     public Component getListCellRendererComponent(JList list, Object value,
 365:         int index, boolean isSelected, boolean cellHasFocus)
 366:     {
 367:       FileFilter filter = (FileFilter) value;
 368:       return super.getListCellRendererComponent(list, filter.getDescription(),
 369:               index, isSelected, cellHasFocus);
 370:     }
 371:   }
 372: 
 373:   /** The model for the directory combo box. */
 374:   DirectoryComboBoxModel directoryModel;
 375:   
 376:   /**
 377:    * A factory method that returns a UI delegate for the specified
 378:    * component.
 379:    * 
 380:    * @param c  the component (which should be a {@link JFileChooser}).
 381:    */
 382:   public static ComponentUI createUI(JComponent c)
 383:   {
 384:     JFileChooser chooser = (JFileChooser) c;
 385:     return new MetalFileChooserUI(chooser);
 386:   }
 387: 
 388:   /**
 389:    * Creates a new instance of this UI delegate.
 390:    * 
 391:    * @param filechooser  the file chooser component.
 392:    */
 393:   public MetalFileChooserUI(JFileChooser filechooser)
 394:   {
 395:     super(filechooser);
 396:   }
 397:   
 398:   /**
 399:    * Creates and returns a new instance of {@link DirectoryComboBoxModel}.
 400:    * 
 401:    * @return A new instance of {@link DirectoryComboBoxModel}.
 402:    */
 403:   protected MetalFileChooserUI.DirectoryComboBoxModel 
 404:       createDirectoryComboBoxModel(JFileChooser fc)
 405:   {
 406:     return new DirectoryComboBoxModel();
 407:   }
 408: 
 409:   /**
 410:    * Creates and returns a new instance of {@link FilterComboBoxModel}.
 411:    * 
 412:    * @return A new instance of {@link FilterComboBoxModel}.
 413:    */
 414:   protected FilterComboBoxModel createFilterComboBoxModel()
 415:   {
 416:     return new FilterComboBoxModel();  
 417:   }
 418: 
 419:   /**
 420:    * Creates and returns a new instance of {@link FilterComboBoxRenderer}.
 421:    * 
 422:    * @return A new instance of {@link FilterComboBoxRenderer}.
 423:    */
 424:   protected MetalFileChooserUI.FilterComboBoxRenderer 
 425:       createFilterComboBoxRenderer()
 426:   {
 427:     return new FilterComboBoxRenderer(); 
 428:   }
 429: 
 430: }