Frames | No Frames |
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: }