001 /* BasicFileChooserUI.java -- 002 Copyright (C) 2005 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 package javax.swing.plaf.basic; 039 040 import java.awt.Window; 041 import java.awt.event.ActionEvent; 042 import java.awt.event.MouseAdapter; 043 import java.awt.event.MouseEvent; 044 import java.awt.event.MouseListener; 045 import java.beans.PropertyChangeEvent; 046 import java.beans.PropertyChangeListener; 047 import java.io.File; 048 import java.io.IOException; 049 import java.util.ArrayList; 050 import java.util.Hashtable; 051 052 import javax.swing.AbstractAction; 053 import javax.swing.Action; 054 import javax.swing.Icon; 055 import javax.swing.JButton; 056 import javax.swing.JComponent; 057 import javax.swing.JDialog; 058 import javax.swing.JFileChooser; 059 import javax.swing.JList; 060 import javax.swing.JPanel; 061 import javax.swing.JTextField; 062 import javax.swing.SwingUtilities; 063 import javax.swing.UIDefaults; 064 import javax.swing.UIManager; 065 import javax.swing.event.ListSelectionEvent; 066 import javax.swing.event.ListSelectionListener; 067 import javax.swing.filechooser.FileFilter; 068 import javax.swing.filechooser.FileSystemView; 069 import javax.swing.filechooser.FileView; 070 import javax.swing.plaf.ComponentUI; 071 import javax.swing.plaf.FileChooserUI; 072 import javax.swing.plaf.metal.MetalIconFactory; 073 074 075 /** 076 * A UI delegate for the {@link JFileChooser} component under the 077 * {@link BasicLookAndFeel}. 078 */ 079 public class BasicFileChooserUI extends FileChooserUI 080 { 081 /** 082 * A file filter that accepts all files. 083 */ 084 protected class AcceptAllFileFilter extends FileFilter 085 { 086 /** 087 * Creates a new instance. 088 */ 089 public AcceptAllFileFilter() 090 { 091 // Nothing to do here. 092 } 093 094 /** 095 * Returns <code>true</code> always, as all files are accepted by this 096 * filter. 097 * 098 * @param f the file. 099 * 100 * @return Always <code>true</code>. 101 */ 102 public boolean accept(File f) 103 { 104 return true; 105 } 106 107 /** 108 * Returns a description for this filter. 109 * 110 * @return A description for the file filter. 111 */ 112 public String getDescription() 113 { 114 return acceptAllFileFilterText; 115 } 116 } 117 118 /** 119 * Handles a user action to approve the dialog selection. 120 * 121 * @see BasicFileChooserUI#getApproveSelectionAction() 122 */ 123 protected class ApproveSelectionAction extends AbstractAction 124 { 125 /** 126 * Creates a new ApproveSelectionAction object. 127 */ 128 protected ApproveSelectionAction() 129 { 130 super("approveSelection"); 131 } 132 133 /** 134 * Sets the current selection and closes the dialog. 135 * 136 * @param e the action event. 137 */ 138 public void actionPerformed(ActionEvent e) 139 { 140 Object obj = null; 141 if (parentPath != null) 142 obj = new String(parentPath + getFileName()); 143 else 144 obj = filechooser.getSelectedFile(); 145 if (obj != null) 146 { 147 File f = filechooser.getFileSystemView().createFileObject(obj.toString()); 148 File currSelected = filechooser.getSelectedFile(); 149 if (filechooser.isTraversable(f)) 150 { 151 filechooser.setCurrentDirectory(currSelected); 152 filechooser.rescanCurrentDirectory(); 153 } 154 else 155 { 156 filechooser.approveSelection(); 157 closeDialog(); 158 } 159 } 160 else 161 { 162 File f = new File(filechooser.getCurrentDirectory(), getFileName()); 163 if ( selectedDir != null ) 164 f = selectedDir; 165 if (filechooser.isTraversable(f)) 166 { 167 filechooser.setCurrentDirectory(f); 168 filechooser.rescanCurrentDirectory(); 169 } 170 else 171 { 172 filechooser.setSelectedFile(f); 173 filechooser.approveSelection(); 174 closeDialog(); 175 } 176 } 177 } 178 } 179 180 /** 181 * Provides presentation information about files and directories. 182 */ 183 protected class BasicFileView extends FileView 184 { 185 /** Storage for cached icons. */ 186 protected Hashtable<File, Icon> iconCache = new Hashtable<File, Icon>(); 187 188 /** 189 * Creates a new instance. 190 */ 191 public BasicFileView() 192 { 193 // Nothing to do here. 194 } 195 196 /** 197 * Adds an icon to the cache, associating it with the given file/directory. 198 * 199 * @param f the file/directory. 200 * @param i the icon. 201 */ 202 public void cacheIcon(File f, Icon i) 203 { 204 iconCache.put(f, i); 205 } 206 207 /** 208 * Clears the icon cache. 209 */ 210 public void clearIconCache() 211 { 212 iconCache.clear(); 213 } 214 215 /** 216 * Retrieves the icon associated with the specified file/directory, if 217 * there is one. 218 * 219 * @param f the file/directory. 220 * 221 * @return The cached icon (or <code>null</code>). 222 */ 223 public Icon getCachedIcon(File f) 224 { 225 return (Icon) iconCache.get(f); 226 } 227 228 /** 229 * Returns a description of the given file/directory. In this 230 * implementation, the description is the same as the name returned by 231 * {@link #getName(File)}. 232 * 233 * @param f the file/directory. 234 * 235 * @return A description of the given file/directory. 236 */ 237 public String getDescription(File f) 238 { 239 return getName(f); 240 } 241 242 /** 243 * Returns an icon appropriate for the given file or directory. 244 * 245 * @param f the file/directory. 246 * 247 * @return An icon. 248 */ 249 public Icon getIcon(File f) 250 { 251 Icon val = getCachedIcon(f); 252 if (val != null) 253 return val; 254 if (filechooser.isTraversable(f)) 255 val = directoryIcon; 256 else 257 val = fileIcon; 258 cacheIcon(f, val); 259 return val; 260 } 261 262 /** 263 * Returns the name for the given file/directory. 264 * 265 * @param f the file/directory. 266 * 267 * @return The name of the file/directory. 268 */ 269 public String getName(File f) 270 { 271 String name = null; 272 if (f != null) 273 { 274 JFileChooser c = getFileChooser(); 275 FileSystemView v = c.getFileSystemView(); 276 name = v.getSystemDisplayName(f); 277 } 278 return name; 279 } 280 281 /** 282 * Returns a localised description for the type of file/directory. 283 * 284 * @param f the file/directory. 285 * 286 * @return A type description for the given file/directory. 287 */ 288 public String getTypeDescription(File f) 289 { 290 if (filechooser.isTraversable(f)) 291 return dirDescText; 292 else 293 return fileDescText; 294 } 295 296 /** 297 * Returns {@link Boolean#TRUE} if the given file/directory is hidden, 298 * and {@link Boolean#FALSE} otherwise. 299 * 300 * @param f the file/directory. 301 * 302 * @return {@link Boolean#TRUE} or {@link Boolean#FALSE}. 303 */ 304 public Boolean isHidden(File f) 305 { 306 return Boolean.valueOf(filechooser.getFileSystemView().isHiddenFile(f)); 307 } 308 } 309 310 /** 311 * Handles an action to cancel the file chooser. 312 * 313 * @see BasicFileChooserUI#getCancelSelectionAction() 314 */ 315 protected class CancelSelectionAction extends AbstractAction 316 { 317 /** 318 * Creates a new <code>CancelSelectionAction</code> object. 319 */ 320 protected CancelSelectionAction() 321 { 322 super(null); 323 } 324 325 /** 326 * Cancels the selection and closes the dialog. 327 * 328 * @param e the action event (ignored). 329 */ 330 public void actionPerformed(ActionEvent e) 331 { 332 filechooser.setSelectedFile(null); 333 filechooser.setSelectedFiles(null); 334 filechooser.cancelSelection(); 335 closeDialog(); 336 } 337 } 338 339 /** 340 * An action to handle changes to the parent directory (for example, via 341 * a click on the "up folder" button). 342 * 343 * @see BasicFileChooserUI#getChangeToParentDirectoryAction() 344 */ 345 protected class ChangeToParentDirectoryAction extends AbstractAction 346 { 347 /** 348 * Creates a new <code>ChangeToParentDirectoryAction</code> object. 349 */ 350 protected ChangeToParentDirectoryAction() 351 { 352 super("Go Up"); 353 } 354 355 /** 356 * Handles the action event. 357 * 358 * @param e the action event. 359 */ 360 public void actionPerformed(ActionEvent e) 361 { 362 filechooser.changeToParentDirectory(); 363 filechooser.revalidate(); 364 filechooser.repaint(); 365 } 366 } 367 368 /** 369 * A mouse listener that handles double-click events. 370 * 371 * @see BasicFileChooserUI#createDoubleClickListener(JFileChooser, JList) 372 */ 373 protected class DoubleClickListener extends MouseAdapter 374 { 375 376 /** DOCUMENT ME! */ 377 private Object lastSelected; 378 379 /** DOCUMENT ME! */ 380 private JList list; 381 382 /** 383 * Creates a new DoubleClickListener object. 384 * 385 * @param list DOCUMENT ME! 386 */ 387 public DoubleClickListener(JList list) 388 { 389 this.list = list; 390 lastSelected = list.getSelectedValue(); 391 setDirectorySelected(false); 392 } 393 394 /** 395 * Handles a mouse click event. 396 * 397 * @param e the event. 398 */ 399 public void mouseClicked(MouseEvent e) 400 { 401 Object p = list.getSelectedValue(); 402 if (p == null) 403 return; 404 FileSystemView fsv = filechooser.getFileSystemView(); 405 if (e.getClickCount() >= 2 && lastSelected != null && 406 p.toString().equals(lastSelected.toString())) 407 { 408 File f = fsv.createFileObject(lastSelected.toString()); 409 if (filechooser.isTraversable(f)) 410 { 411 filechooser.setCurrentDirectory(f); 412 filechooser.rescanCurrentDirectory(); 413 } 414 else 415 { 416 filechooser.setSelectedFile(f); 417 filechooser.approveSelection(); 418 closeDialog(); 419 } 420 } 421 else // single click 422 { 423 String path = p.toString(); 424 File f = fsv.createFileObject(path); 425 filechooser.setSelectedFile(f); 426 427 if (filechooser.isMultiSelectionEnabled()) 428 { 429 int[] inds = list.getSelectedIndices(); 430 File[] allFiles = new File[inds.length]; 431 for (int i = 0; i < inds.length; i++) 432 allFiles[i] = (File) list.getModel().getElementAt(inds[i]); 433 filechooser.setSelectedFiles(allFiles); 434 } 435 436 if (filechooser.isTraversable(f)) 437 { 438 setDirectorySelected(true); 439 setDirectory(f); 440 } 441 else 442 { 443 setDirectorySelected(false); 444 setDirectory(null); 445 } 446 lastSelected = path; 447 parentPath = f.getParent(); 448 449 if (f.isFile()) 450 setFileName(f.getName()); 451 else if (filechooser.getFileSelectionMode() != 452 JFileChooser.FILES_ONLY) 453 setFileName(path); 454 } 455 } 456 457 /** 458 * Handles a mouse entered event (NOT IMPLEMENTED). 459 * 460 * @param e the mouse event. 461 */ 462 public void mouseEntered(MouseEvent e) 463 { 464 // FIXME: Implement 465 } 466 } 467 468 /** 469 * An action that changes the file chooser to display the user's home 470 * directory. 471 * 472 * @see BasicFileChooserUI#getGoHomeAction() 473 */ 474 protected class GoHomeAction extends AbstractAction 475 { 476 /** 477 * Creates a new <code>GoHomeAction</code> object. 478 */ 479 protected GoHomeAction() 480 { 481 super("Go Home"); 482 } 483 484 /** 485 * Sets the directory to the user's home directory, and repaints the 486 * file chooser component. 487 * 488 * @param e the action event (ignored). 489 */ 490 public void actionPerformed(ActionEvent e) 491 { 492 filechooser.setCurrentDirectory(filechooser.getFileSystemView() 493 .getHomeDirectory()); 494 filechooser.revalidate(); 495 filechooser.repaint(); 496 } 497 } 498 499 /** 500 * An action that handles the creation of a new folder/directory. 501 * 502 * @see BasicFileChooserUI#getNewFolderAction() 503 */ 504 protected class NewFolderAction extends AbstractAction 505 { 506 /** 507 * Creates a new <code>NewFolderAction</code> object. 508 */ 509 protected NewFolderAction() 510 { 511 super("New Folder"); 512 } 513 514 /** 515 * Handles the event by creating a new folder. 516 * 517 * @param e the action event (ignored). 518 */ 519 public void actionPerformed(ActionEvent e) 520 { 521 try 522 { 523 filechooser.getFileSystemView().createNewFolder(filechooser 524 .getCurrentDirectory()); 525 } 526 catch (IOException ioe) 527 { 528 return; 529 } 530 filechooser.rescanCurrentDirectory(); 531 filechooser.repaint(); 532 } 533 } 534 535 /** 536 * A listener for selection events in the file list. 537 * 538 * @see BasicFileChooserUI#createListSelectionListener(JFileChooser) 539 */ 540 protected class SelectionListener implements ListSelectionListener 541 { 542 /** 543 * Creates a new <code>SelectionListener</code> object. 544 */ 545 protected SelectionListener() 546 { 547 // Nothing to do here. 548 } 549 550 /** 551 * Sets the JFileChooser to the selected file on an update 552 * 553 * @param e DOCUMENT ME! 554 */ 555 public void valueChanged(ListSelectionEvent e) 556 { 557 JList list = (JList) e.getSource(); 558 Object f = list.getSelectedValue(); 559 if (f == null) 560 return; 561 File file = filechooser.getFileSystemView().createFileObject(f.toString()); 562 if (! filechooser.isTraversable(file)) 563 { 564 selectedDir = null; 565 filechooser.setSelectedFile(file); 566 } 567 else 568 { 569 selectedDir = file; 570 filechooser.setSelectedFile(null); 571 } 572 } 573 } 574 575 /** 576 * DOCUMENT ME! 577 * 578 * @see BasicFileChooserUI#getUpdateAction() 579 */ 580 protected class UpdateAction extends AbstractAction 581 { 582 /** 583 * Creates a new UpdateAction object. 584 */ 585 protected UpdateAction() 586 { 587 super(null); 588 } 589 590 /** 591 * NOT YET IMPLEMENTED. 592 * 593 * @param e the action event. 594 */ 595 public void actionPerformed(ActionEvent e) 596 { 597 // FIXME: implement this 598 } 599 } 600 601 /** The localised mnemonic for the cancel button. */ 602 protected int cancelButtonMnemonic; 603 604 /** The localised text for the cancel button. */ 605 protected String cancelButtonText; 606 607 /** The localised tool tip text for the cancel button. */ 608 protected String cancelButtonToolTipText; 609 610 /** An icon representing a computer. */ 611 protected Icon computerIcon; 612 613 /** An icon for the "details view" button. */ 614 protected Icon detailsViewIcon; 615 616 /** An icon representing a directory. */ 617 protected Icon directoryIcon; 618 619 /** The localised Mnemonic for the open button. */ 620 protected int directoryOpenButtonMnemonic; 621 622 /** The localised text for the open button. */ 623 protected String directoryOpenButtonText; 624 625 /** The localised tool tip text for the open button. */ 626 protected String directoryOpenButtonToolTipText; 627 628 /** An icon representing a file. */ 629 protected Icon fileIcon; 630 631 /** An icon representing a floppy drive. */ 632 protected Icon floppyDriveIcon; 633 634 /** An icon representing a hard drive. */ 635 protected Icon hardDriveIcon; 636 637 /** The localised mnemonic for the "help" button. */ 638 protected int helpButtonMnemonic; 639 640 /** The localised text for the "help" button. */ 641 protected String helpButtonText; 642 643 /** The localised tool tip text for the help button. */ 644 protected String helpButtonToolTipText; 645 646 /** An icon representing the user's home folder. */ 647 protected Icon homeFolderIcon; 648 649 /** An icon for the "list view" button. */ 650 protected Icon listViewIcon; 651 652 /** An icon for the "new folder" button. */ 653 protected Icon newFolderIcon = directoryIcon; 654 655 /** The localised mnemonic for the "open" button. */ 656 protected int openButtonMnemonic; 657 658 /** The localised text for the "open" button. */ 659 protected String openButtonText; 660 661 /** The localised tool tip text for the "open" button. */ 662 protected String openButtonToolTipText; 663 664 /** The localised mnemonic for the "save" button. */ 665 protected int saveButtonMnemonic; 666 667 /** The localised text for the "save" button. */ 668 protected String saveButtonText; 669 670 /** The localised tool tip text for the save button. */ 671 protected String saveButtonToolTipText; 672 673 /** The localised mnemonic for the "update" button. */ 674 protected int updateButtonMnemonic; 675 676 /** The localised text for the "update" button. */ 677 protected String updateButtonText; 678 679 /** The localised tool tip text for the "update" button. */ 680 protected String updateButtonToolTipText; 681 682 /** An icon for the "up folder" button. */ 683 protected Icon upFolderIcon; 684 685 // -- begin private, but package local since used in inner classes -- 686 687 /** The file chooser component represented by this UI delegate. */ 688 JFileChooser filechooser; 689 690 /** The model for the directory list. */ 691 BasicDirectoryModel model; 692 693 /** The file filter for all files. */ 694 FileFilter acceptAll = new AcceptAllFileFilter(); 695 696 /** The default file view. */ 697 FileView fv = new BasicFileView(); 698 699 /** The accept (open/save) button. */ 700 JButton accept; 701 702 /** An optional accessory panel. */ 703 JPanel accessoryPanel = new JPanel(); 704 705 /** A property change listener. */ 706 PropertyChangeListener propertyChangeListener; 707 708 /** The text describing the filter for "all files". */ 709 String acceptAllFileFilterText; 710 711 /** The text describing a directory type. */ 712 String dirDescText; 713 714 /** The text describing a file type. */ 715 String fileDescText; 716 717 /** Is a directory selected? */ 718 boolean dirSelected; 719 720 /** The current directory. */ 721 File currDir; 722 723 // FIXME: describe what is contained in the bottom panel 724 /** The bottom panel. */ 725 JPanel bottomPanel; 726 727 /** The close panel. */ 728 JPanel closePanel; 729 730 /** Text box that displays file name */ 731 JTextField entry; 732 733 /** Current parent path */ 734 String parentPath; 735 736 /** 737 * The action for the 'approve' button. 738 * @see #getApproveSelectionAction() 739 */ 740 private ApproveSelectionAction approveSelectionAction; 741 742 /** 743 * The action for the 'cancel' button. 744 * @see #getCancelSelectionAction() 745 */ 746 private CancelSelectionAction cancelSelectionAction; 747 748 /** 749 * The action for the 'go home' control button. 750 * @see #getGoHomeAction() 751 */ 752 private GoHomeAction goHomeAction; 753 754 /** 755 * The action for the 'up folder' control button. 756 * @see #getChangeToParentDirectoryAction() 757 */ 758 private ChangeToParentDirectoryAction changeToParentDirectoryAction; 759 760 /** 761 * The action for the 'new folder' control button. 762 * @see #getNewFolderAction() 763 */ 764 private NewFolderAction newFolderAction; 765 766 /** 767 * The action for ???. // FIXME: what is this? 768 * @see #getUpdateAction() 769 */ 770 private UpdateAction updateAction; 771 772 /** 773 * When in FILES_ONLY, mode a directory cannot be selected, so 774 * we save a reference to any it here. This is used to enter 775 * the directory on "Open" when in that mode. 776 */ 777 private File selectedDir; 778 779 // -- end private -- 780 781 /** 782 * Closes the dialog. 783 */ 784 void closeDialog() 785 { 786 Window owner = SwingUtilities.windowForComponent(filechooser); 787 if (owner instanceof JDialog) 788 ((JDialog) owner).dispose(); 789 } 790 791 /** 792 * Creates a new <code>BasicFileChooserUI</code> object. 793 * 794 * @param b the file chooser component. 795 */ 796 public BasicFileChooserUI(JFileChooser b) 797 { 798 } 799 800 /** 801 * Returns a UI delegate for the given component. 802 * 803 * @param c the component (should be a {@link JFileChooser}). 804 * 805 * @return A new UI delegate. 806 */ 807 public static ComponentUI createUI(JComponent c) 808 { 809 return new BasicFileChooserUI((JFileChooser) c); 810 } 811 812 /** 813 * Installs the UI for the specified component. 814 * 815 * @param c the component (should be a {@link JFileChooser}). 816 */ 817 public void installUI(JComponent c) 818 { 819 if (c instanceof JFileChooser) 820 { 821 JFileChooser fc = (JFileChooser) c; 822 this.filechooser = fc; 823 fc.resetChoosableFileFilters(); 824 createModel(); 825 clearIconCache(); 826 installDefaults(fc); 827 installComponents(fc); 828 installListeners(fc); 829 830 File path = filechooser.getCurrentDirectory(); 831 if (path != null) 832 parentPath = path.getParent(); 833 } 834 } 835 836 /** 837 * Uninstalls this UI from the given component. 838 * 839 * @param c the component (should be a {@link JFileChooser}). 840 */ 841 public void uninstallUI(JComponent c) 842 { 843 model = null; 844 uninstallListeners(filechooser); 845 uninstallComponents(filechooser); 846 uninstallDefaults(filechooser); 847 filechooser = null; 848 } 849 850 // FIXME: Indent the entries in the combobox 851 // Made this method package private to access it from within inner classes 852 // with better performance 853 void boxEntries() 854 { 855 ArrayList parentFiles = new ArrayList(); 856 File parent = filechooser.getCurrentDirectory(); 857 if (parent == null) 858 parent = filechooser.getFileSystemView().getDefaultDirectory(); 859 while (parent != null) 860 { 861 String name = parent.getName(); 862 if (name.equals("")) 863 name = parent.getAbsolutePath(); 864 865 parentFiles.add(parentFiles.size(), name); 866 parent = parent.getParentFile(); 867 } 868 869 if (parentFiles.size() == 0) 870 return; 871 872 } 873 874 /** 875 * Creates and install the subcomponents for the file chooser. 876 * 877 * @param fc the file chooser. 878 */ 879 public void installComponents(JFileChooser fc) 880 { 881 } 882 883 /** 884 * Uninstalls the components from the file chooser. 885 * 886 * @param fc the file chooser. 887 */ 888 public void uninstallComponents(JFileChooser fc) 889 { 890 } 891 892 /** 893 * Installs the listeners required by this UI delegate. 894 * 895 * @param fc the file chooser. 896 */ 897 protected void installListeners(JFileChooser fc) 898 { 899 propertyChangeListener = createPropertyChangeListener(filechooser); 900 if (propertyChangeListener != null) 901 filechooser.addPropertyChangeListener(propertyChangeListener); 902 fc.addPropertyChangeListener(getModel()); 903 } 904 905 /** 906 * Uninstalls the listeners previously installed by this UI delegate. 907 * 908 * @param fc the file chooser. 909 */ 910 protected void uninstallListeners(JFileChooser fc) 911 { 912 if (propertyChangeListener != null) 913 { 914 filechooser.removePropertyChangeListener(propertyChangeListener); 915 propertyChangeListener = null; 916 } 917 fc.removePropertyChangeListener(getModel()); 918 } 919 920 /** 921 * Installs the defaults for this UI delegate. 922 * 923 * @param fc the file chooser. 924 */ 925 protected void installDefaults(JFileChooser fc) 926 { 927 installIcons(fc); 928 installStrings(fc); 929 } 930 931 /** 932 * Uninstalls the defaults previously added by this UI delegate. 933 * 934 * @param fc the file chooser. 935 */ 936 protected void uninstallDefaults(JFileChooser fc) 937 { 938 uninstallStrings(fc); 939 uninstallIcons(fc); 940 } 941 942 /** 943 * Installs the icons for this UI delegate. 944 * 945 * @param fc the file chooser (ignored). 946 */ 947 protected void installIcons(JFileChooser fc) 948 { 949 UIDefaults defaults = UIManager.getLookAndFeelDefaults(); 950 computerIcon = MetalIconFactory.getTreeComputerIcon(); 951 detailsViewIcon = defaults.getIcon("FileChooser.detailsViewIcon"); 952 directoryIcon = new MetalIconFactory.TreeFolderIcon(); 953 fileIcon = new MetalIconFactory.TreeLeafIcon(); 954 floppyDriveIcon = MetalIconFactory.getTreeFloppyDriveIcon(); 955 hardDriveIcon = MetalIconFactory.getTreeHardDriveIcon(); 956 homeFolderIcon = defaults.getIcon("FileChooser.homeFolderIcon"); 957 listViewIcon = defaults.getIcon("FileChooser.listViewIcon"); 958 newFolderIcon = defaults.getIcon("FileChooser.newFolderIcon"); 959 upFolderIcon = defaults.getIcon("FileChooser.upFolderIcon"); 960 } 961 962 /** 963 * Uninstalls the icons previously added by this UI delegate. 964 * 965 * @param fc the file chooser. 966 */ 967 protected void uninstallIcons(JFileChooser fc) 968 { 969 computerIcon = null; 970 detailsViewIcon = null; 971 directoryIcon = null; 972 fileIcon = null; 973 floppyDriveIcon = null; 974 hardDriveIcon = null; 975 homeFolderIcon = null; 976 listViewIcon = null; 977 newFolderIcon = null; 978 upFolderIcon = null; 979 } 980 981 /** 982 * Installs the strings used by this UI delegate. 983 * 984 * @param fc the file chooser. 985 */ 986 protected void installStrings(JFileChooser fc) 987 { 988 UIDefaults defaults = UIManager.getLookAndFeelDefaults(); 989 990 dirDescText = defaults.getString("FileChooser.directoryDescriptionText"); 991 fileDescText = defaults.getString("FileChooser.fileDescriptionText"); 992 993 acceptAllFileFilterText = defaults.getString("FileChooser.acceptAllFileFilterText"); 994 cancelButtonText = "Cancel"; 995 cancelButtonToolTipText = "Abort file chooser dialog"; 996 cancelButtonMnemonic = new Integer((String) UIManager.get("FileChooser.cancelButtonMnemonic")).intValue(); 997 998 directoryOpenButtonText = "Open"; 999 directoryOpenButtonToolTipText = "Open selected directory"; 1000 directoryOpenButtonMnemonic 1001 = new Integer((String) UIManager.get("FileChooser.directoryOpenButtonMnemonic")).intValue(); 1002 1003 helpButtonText = "Help"; 1004 helpButtonToolTipText = "FileChooser help"; 1005 helpButtonMnemonic = new Integer((String) UIManager.get("FileChooser.helpButtonMnemonic")).intValue(); 1006 1007 openButtonText = "Open"; 1008 openButtonToolTipText = "Open selected file"; 1009 openButtonMnemonic = new Integer((String) UIManager.get("FileChooser.openButtonMnemonic")).intValue(); 1010 1011 saveButtonText = "Save"; 1012 saveButtonToolTipText = "Save selected file"; 1013 saveButtonMnemonic = new Integer((String) UIManager.get("FileChooser.saveButtonMnemonic")).intValue(); 1014 1015 updateButtonText = "Update"; 1016 updateButtonToolTipText = "Update directory listing"; 1017 updateButtonMnemonic = new Integer((String) UIManager.get("FileChooser.updateButtonMnemonic")).intValue(); 1018 } 1019 1020 /** 1021 * Uninstalls the strings previously added by this UI delegate. 1022 * 1023 * @param fc the file chooser. 1024 */ 1025 protected void uninstallStrings(JFileChooser fc) 1026 { 1027 acceptAllFileFilterText = null; 1028 dirDescText = null; 1029 fileDescText = null; 1030 1031 cancelButtonText = null; 1032 cancelButtonToolTipText = null; 1033 1034 directoryOpenButtonText = null; 1035 directoryOpenButtonToolTipText = null; 1036 1037 helpButtonText = null; 1038 helpButtonToolTipText = null; 1039 1040 openButtonText = null; 1041 openButtonToolTipText = null; 1042 1043 saveButtonText = null; 1044 saveButtonToolTipText = null; 1045 1046 updateButtonText = null; 1047 updateButtonToolTipText = null; 1048 } 1049 1050 /** 1051 * Creates a new directory model. 1052 */ 1053 protected void createModel() 1054 { 1055 model = new BasicDirectoryModel(filechooser); 1056 } 1057 1058 /** 1059 * Returns the directory model. 1060 * 1061 * @return The directory model. 1062 */ 1063 public BasicDirectoryModel getModel() 1064 { 1065 return model; 1066 } 1067 1068 /** 1069 * Creates a listener to handle changes to the properties of the given 1070 * file chooser component. 1071 * 1072 * @param fc the file chooser component. 1073 * 1074 * @return A new listener. 1075 */ 1076 public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) 1077 { 1078 // The RI returns null here, so do we. 1079 return null; 1080 } 1081 1082 /** 1083 * Returns the current file name. 1084 * 1085 * @return The current file name. 1086 */ 1087 public String getFileName() 1088 { 1089 return entry.getText(); 1090 } 1091 1092 /** 1093 * Returns the current directory name. 1094 * 1095 * @return The directory name. 1096 * 1097 * @see #setDirectoryName(String) 1098 */ 1099 public String getDirectoryName() 1100 { 1101 // XXX: I don't see a case where the thing returns something non-null.. 1102 return null; 1103 } 1104 1105 /** 1106 * Sets the file name. 1107 * 1108 * @param filename the file name. 1109 * 1110 * @see #getFileName() 1111 */ 1112 public void setFileName(String filename) 1113 { 1114 // FIXME: it might be the case that this method provides an access 1115 // point for the JTextField (or whatever) a subclass is using... 1116 //this.filename = filename; 1117 } 1118 1119 /** 1120 * Sets the directory name (NOT IMPLEMENTED). 1121 * 1122 * @param dirname the directory name. 1123 * 1124 * @see #getDirectoryName() 1125 */ 1126 public void setDirectoryName(String dirname) 1127 { 1128 // FIXME: Implement 1129 } 1130 1131 /** 1132 * Rescans the current directory. 1133 * 1134 * @param fc the file chooser. 1135 */ 1136 public void rescanCurrentDirectory(JFileChooser fc) 1137 { 1138 getModel().validateFileCache(); 1139 } 1140 1141 /** 1142 * NOT YET IMPLEMENTED. 1143 * 1144 * @param fc the file chooser. 1145 * @param f the file. 1146 */ 1147 public void ensureFileIsVisible(JFileChooser fc, File f) 1148 { 1149 // XXX: Not sure what this does. 1150 } 1151 1152 /** 1153 * Returns the {@link JFileChooser} component that this UI delegate 1154 * represents. 1155 * 1156 * @return The component represented by this UI delegate. 1157 */ 1158 public JFileChooser getFileChooser() 1159 { 1160 return filechooser; 1161 } 1162 1163 /** 1164 * Returns the optional accessory panel. 1165 * 1166 * @return The optional accessory panel. 1167 */ 1168 public JPanel getAccessoryPanel() 1169 { 1170 return accessoryPanel; 1171 } 1172 1173 /** 1174 * Returns the approve (open or save) button for the dialog. 1175 * 1176 * @param fc the file chooser. 1177 * 1178 * @return The button. 1179 */ 1180 protected JButton getApproveButton(JFileChooser fc) 1181 { 1182 return accept; 1183 } 1184 1185 /** 1186 * Returns the tool tip text for the approve (open/save) button. This first 1187 * checks the file chooser to see if a value has been explicitly set - if 1188 * not, a default value appropriate for the type of file chooser is 1189 * returned. 1190 * 1191 * @param fc the file chooser. 1192 * 1193 * @return The tool tip text. 1194 */ 1195 public String getApproveButtonToolTipText(JFileChooser fc) 1196 { 1197 if (fc.getApproveButtonToolTipText() != null) 1198 return fc.getApproveButtonToolTipText(); 1199 else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) 1200 return saveButtonToolTipText; 1201 else 1202 return openButtonToolTipText; 1203 } 1204 1205 /** 1206 * Clears the icon cache. 1207 */ 1208 public void clearIconCache() 1209 { 1210 if (fv instanceof BasicFileView) 1211 ((BasicFileView) fv).clearIconCache(); 1212 } 1213 1214 /** 1215 * Creates a new listener to handle selections in the file list. 1216 * 1217 * @param fc the file chooser component. 1218 * 1219 * @return A new instance of {@link SelectionListener}. 1220 */ 1221 public ListSelectionListener createListSelectionListener(JFileChooser fc) 1222 { 1223 return new SelectionListener(); 1224 } 1225 1226 /** 1227 * Creates a new listener to handle double-click events. 1228 * 1229 * @param fc the file chooser component. 1230 * @param list the list. 1231 * 1232 * @return A new instance of {@link DoubleClickListener}. 1233 */ 1234 protected MouseListener createDoubleClickListener(JFileChooser fc, JList list) 1235 { 1236 return new DoubleClickListener(list); 1237 } 1238 1239 /** 1240 * Returns <code>true</code> if a directory is selected, and 1241 * <code>false</code> otherwise. 1242 * 1243 * @return A boolean. 1244 */ 1245 protected boolean isDirectorySelected() 1246 { 1247 return dirSelected; 1248 } 1249 1250 /** 1251 * Sets the flag that indicates whether the current directory is selected. 1252 * 1253 * @param selected the new flag value. 1254 */ 1255 protected void setDirectorySelected(boolean selected) 1256 { 1257 dirSelected = selected; 1258 } 1259 1260 /** 1261 * Returns the current directory. 1262 * 1263 * @return The current directory. 1264 */ 1265 protected File getDirectory() 1266 { 1267 return currDir; 1268 } 1269 1270 /** 1271 * Sets the current directory. 1272 * 1273 * @param f the directory. 1274 */ 1275 protected void setDirectory(File f) 1276 { 1277 currDir = f; 1278 } 1279 1280 /** 1281 * Returns the "accept all" file filter. 1282 * 1283 * @param fc the file chooser component. 1284 * 1285 * @return The "accept all" file filter. 1286 */ 1287 public FileFilter getAcceptAllFileFilter(JFileChooser fc) 1288 { 1289 return acceptAll; 1290 } 1291 1292 /** 1293 * Returns the default file view (NOT the file view from the file chooser, 1294 * if there is one). 1295 * 1296 * @param fc the file chooser component. 1297 * 1298 * @return The file view. 1299 * 1300 * @see JFileChooser#getFileView() 1301 */ 1302 public FileView getFileView(JFileChooser fc) 1303 { 1304 return fv; 1305 } 1306 1307 /** 1308 * Returns the dialog title. 1309 * 1310 * @param fc the file chooser (<code>null</code> not permitted). 1311 * 1312 * @return The dialog title. 1313 * 1314 * @see JFileChooser#getDialogTitle() 1315 */ 1316 public String getDialogTitle(JFileChooser fc) 1317 { 1318 String result = fc.getDialogTitle(); 1319 if (result == null) 1320 result = getApproveButtonText(fc); 1321 return result; 1322 } 1323 1324 /** 1325 * Returns the approve button mnemonic. 1326 * 1327 * @param fc the file chooser (<code>null</code> not permitted). 1328 * 1329 * @return The approve button mnemonic. 1330 * 1331 * @see JFileChooser#getApproveButtonMnemonic() 1332 */ 1333 public int getApproveButtonMnemonic(JFileChooser fc) 1334 { 1335 if (fc.getApproveButtonMnemonic() != 0) 1336 return fc.getApproveButtonMnemonic(); 1337 else if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) 1338 return saveButtonMnemonic; 1339 else 1340 return openButtonMnemonic; 1341 } 1342 1343 /** 1344 * Returns the approve button text. 1345 * 1346 * @param fc the file chooser (<code>null</code> not permitted). 1347 * 1348 * @return The approve button text. 1349 * 1350 * @see JFileChooser#getApproveButtonText() 1351 */ 1352 public String getApproveButtonText(JFileChooser fc) 1353 { 1354 String result = fc.getApproveButtonText(); 1355 if (result == null) 1356 { 1357 if (fc.getDialogType() == JFileChooser.SAVE_DIALOG) 1358 result = saveButtonText; 1359 else 1360 result = openButtonText; 1361 } 1362 return result; 1363 } 1364 1365 /** 1366 * Creates and returns a new action that will be used with the "new folder" 1367 * button. 1368 * 1369 * @return A new instance of {@link NewFolderAction}. 1370 */ 1371 public Action getNewFolderAction() 1372 { 1373 if (newFolderAction == null) 1374 newFolderAction = new NewFolderAction(); 1375 return newFolderAction; 1376 } 1377 1378 /** 1379 * Creates and returns a new action that will be used with the "home folder" 1380 * button. 1381 * 1382 * @return A new instance of {@link GoHomeAction}. 1383 */ 1384 public Action getGoHomeAction() 1385 { 1386 if (goHomeAction == null) 1387 goHomeAction = new GoHomeAction(); 1388 return goHomeAction; 1389 } 1390 1391 /** 1392 * Returns the action that handles events for the "up folder" control button. 1393 * 1394 * @return An instance of {@link ChangeToParentDirectoryAction}. 1395 */ 1396 public Action getChangeToParentDirectoryAction() 1397 { 1398 if (changeToParentDirectoryAction == null) 1399 changeToParentDirectoryAction = new ChangeToParentDirectoryAction(); 1400 return changeToParentDirectoryAction; 1401 } 1402 1403 /** 1404 * Returns the action that handles events for the "approve" button. 1405 * 1406 * @return An instance of {@link ApproveSelectionAction}. 1407 */ 1408 public Action getApproveSelectionAction() 1409 { 1410 if (approveSelectionAction == null) 1411 approveSelectionAction = new ApproveSelectionAction(); 1412 return approveSelectionAction; 1413 } 1414 1415 /** 1416 * Returns the action that handles events for the "cancel" button. 1417 * 1418 * @return An instance of {@link CancelSelectionAction}. 1419 */ 1420 public Action getCancelSelectionAction() 1421 { 1422 if (cancelSelectionAction == null) 1423 cancelSelectionAction = new CancelSelectionAction(); 1424 return cancelSelectionAction; 1425 } 1426 1427 /** 1428 * Returns the update action (an instance of {@link UpdateAction}). 1429 * 1430 * @return An action. 1431 */ 1432 public Action getUpdateAction() 1433 { 1434 if (updateAction == null) 1435 updateAction = new UpdateAction(); 1436 return updateAction; 1437 } 1438 }