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