/[classpath]/classpath/javax/swing/plaf/metal/MetalFileChooserUI.java
ViewVC logotype

Diff of /classpath/javax/swing/plaf/metal/MetalFileChooserUI.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3.2.1 by gnu_andrew, Wed Nov 2 00:44:00 2005 UTC revision 1.3.2.2 by gnu_andrew, Sun Nov 27 21:00:41 2005 UTC
# Line 38  exception statement from your version. * Line 38  exception statement from your version. *
38    
39  package javax.swing.plaf.metal;  package javax.swing.plaf.metal;
40    
41    import java.awt.BorderLayout;
42  import java.awt.Component;  import java.awt.Component;
43    import java.awt.Container;
44    import java.awt.Dimension;
45    import java.awt.GridLayout;
46    import java.awt.Insets;
47    import java.awt.LayoutManager;
48    import java.awt.Rectangle;
49    import java.awt.Window;
50  import java.awt.event.ActionEvent;  import java.awt.event.ActionEvent;
51    import java.awt.event.MouseAdapter;
52    import java.awt.event.MouseEvent;
53    
54  import java.beans.PropertyChangeEvent;  import java.beans.PropertyChangeEvent;
55  import java.beans.PropertyChangeListener;  import java.beans.PropertyChangeListener;
56    
57  import java.io.File;  import java.io.File;
 import java.util.List;  
58    
59  import javax.swing.AbstractAction;  import javax.swing.AbstractAction;
60  import javax.swing.AbstractListModel;  import javax.swing.AbstractListModel;
61    import javax.swing.ActionMap;
62    import javax.swing.BorderFactory;
63    import javax.swing.ButtonGroup;
64  import javax.swing.ComboBoxModel;  import javax.swing.ComboBoxModel;
65  import javax.swing.DefaultListCellRenderer;  import javax.swing.DefaultListCellRenderer;
66    import javax.swing.Icon;
67    import javax.swing.JButton;
68    import javax.swing.JComboBox;
69  import javax.swing.JComponent;  import javax.swing.JComponent;
70    import javax.swing.JDialog;
71  import javax.swing.JFileChooser;  import javax.swing.JFileChooser;
72    import javax.swing.JLabel;
73  import javax.swing.JList;  import javax.swing.JList;
74    import javax.swing.JPanel;
75    import javax.swing.JScrollPane;
76    import javax.swing.JTextField;
77    import javax.swing.JToggleButton;
78    import javax.swing.ListSelectionModel;
79    import javax.swing.SwingUtilities;
80  import javax.swing.UIManager;  import javax.swing.UIManager;
81    import javax.swing.event.ListSelectionEvent;
82    import javax.swing.event.ListSelectionListener;
83  import javax.swing.filechooser.FileFilter;  import javax.swing.filechooser.FileFilter;
84  import javax.swing.filechooser.FileSystemView;  import javax.swing.filechooser.FileSystemView;
85  import javax.swing.filechooser.FileView;  import javax.swing.filechooser.FileView;
86  import javax.swing.plaf.ComponentUI;  import javax.swing.plaf.ComponentUI;
87  import javax.swing.plaf.basic.BasicFileChooserUI;  import javax.swing.plaf.basic.BasicFileChooserUI;
88    
89    import java.util.List;
90    
91    
92  /**  /**
93   * A UI delegate for the {@link JFileChooser} component.  This class is only   * A UI delegate for the {@link JFileChooser} component.  This class is only
94   * partially implemented and is not usable yet.   * partially implemented and is not usable yet.
95   */   */
96  public class MetalFileChooserUI extends BasicFileChooserUI  public class MetalFileChooserUI
97      extends BasicFileChooserUI
98  {  {
99      
100      /**
101       * A property change listener.
102       */
103      class MetalFileChooserPropertyChangeListener
104        implements PropertyChangeListener
105      {
106        /**
107         * Default constructor.
108         */
109        public MetalFileChooserPropertyChangeListener()
110        {
111        }
112        
113        /**
114         * Handles a property change event.
115         *
116         * @param e  the event.
117         */
118        public void propertyChange(PropertyChangeEvent e)
119        {
120          JFileChooser filechooser = getFileChooser();
121          
122          String n = e.getPropertyName();
123          if (n.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY))
124            {
125              if (filechooser.isMultiSelectionEnabled())
126                fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
127              else
128                fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
129            }
130          else if (n.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY))
131            {
132              File file = filechooser.getSelectedFile();
133              if (file == null)
134                setFileName(null);
135              else
136                setFileName(file.getName());
137              int index = -1;
138              index = getModel().indexOf(file);
139              if (index >= 0)
140                {
141                  fileList.setSelectedIndex(index);
142                  fileList.ensureIndexIsVisible(index);
143                  fileList.revalidate();
144                  fileList.repaint();
145                }
146            }
147          
148          else if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY))
149            {
150              fileList.clearSelection();
151              fileList.revalidate();
152              fileList.repaint();
153              setDirectorySelected(false);
154              File currentDirectory = filechooser.getCurrentDirectory();
155              setDirectory(currentDirectory);
156              boolean hasParent = (currentDirectory.getParentFile() != null);
157              getChangeToParentDirectoryAction().setEnabled(hasParent);
158            }
159          
160          else if (n.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
161            {
162              filterModel.propertyChange(e);
163            }
164          else if (n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
165            {
166              filterModel.propertyChange(e);
167            }
168          else if (n.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)
169                     || n.equals(JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY))
170            {
171              Window owner = SwingUtilities.windowForComponent(filechooser);
172              if (owner instanceof JDialog)
173                ((JDialog) owner).setTitle(getDialogTitle(filechooser));
174              approveButton.setText(getApproveButtonText(filechooser));
175              approveButton.setToolTipText(
176                      getApproveButtonToolTipText(filechooser));
177              approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
178            }
179          
180          else if (n.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY))
181            approveButton.setText(getApproveButtonText(filechooser));
182          
183          else if (n.equals(
184                  JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY))
185            approveButton.setToolTipText(getApproveButtonToolTipText(filechooser));
186          
187          else if (n.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY))
188            approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
189    
190          else if (n.equals(
191                  JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY))
192            {
193              if (filechooser.getControlButtonsAreShown())
194                {
195                  topPanel.add(controls, BorderLayout.EAST);
196                }
197              else
198                topPanel.remove(controls);
199              topPanel.revalidate();
200              topPanel.repaint();
201              topPanel.doLayout();
202            }
203          
204          else if (n.equals(
205                  JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY))
206            {
207              if (filechooser.isAcceptAllFileFilterUsed())
208                filechooser.addChoosableFileFilter(
209                        getAcceptAllFileFilter(filechooser));
210              else
211                filechooser.removeChoosableFileFilter(
212                        getAcceptAllFileFilter(filechooser));
213            }
214          
215          else if (n.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY))
216            {
217              JComponent old = (JComponent) e.getOldValue();
218              if (old != null)
219                getAccessoryPanel().remove(old);
220              JComponent newval = (JComponent) e.getNewValue();
221              if (newval != null)
222                getAccessoryPanel().add(newval);
223            }
224          
225          if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)
226              || n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)
227              || n.equals(JFileChooser.FILE_HIDING_CHANGED_PROPERTY))
228            rescanCurrentDirectory(filechooser);
229          
230          filechooser.revalidate();
231          filechooser.repaint();
232        }
233      };
234      
235    /**    /**
236     * A combo box model containing the selected directory and all its parent     * A combo box model containing the selected directory and all its parent
237     * directories.     * directories.
238     */     */
239    protected class DirectoryComboBoxModel extends AbstractListModel    protected class DirectoryComboBoxModel
240        extends AbstractListModel
241      implements ComboBoxModel      implements ComboBoxModel
242    {    {
243      /** Storage for the items in the model. */      /** Storage for the items in the model. */
# Line 161  public class MetalFileChooserUI extends Line 328  public class MetalFileChooserUI extends
328    /**    /**
329     * Handles changes to the selection in the directory combo box.     * Handles changes to the selection in the directory combo box.
330     */     */
331    protected class DirectoryComboBoxAction extends AbstractAction    protected class DirectoryComboBoxAction
332        extends AbstractAction
333    {    {
334      /**      /**
335       * Creates a new action.       * Creates a new action.
# Line 184  public class MetalFileChooserUI extends Line 352  public class MetalFileChooserUI extends
352    }    }
353    
354    /**    /**
355       * A renderer for the items in the directory combo box.
356       */
357      class DirectoryComboBoxRenderer
358        extends DefaultListCellRenderer
359      {
360        /**
361         * Creates a new renderer.
362         */
363        public DirectoryComboBoxRenderer(JFileChooser fc)
364        {
365        }
366        
367        /**
368         * Returns a component that can be used to paint the given value within
369         * the list.
370         *
371         * @param list  the list.
372         * @param value  the value (a {@link File}).
373         * @param index  the item index.
374         * @param isSelected  is the item selected?
375         * @param cellHasFocus  does the list cell have focus?
376         *
377         * @return The list cell renderer.
378         */
379        public Component getListCellRendererComponent(JList list, Object value,
380            int index, boolean isSelected, boolean cellHasFocus)
381        {
382          FileView fileView = getFileView(getFileChooser());
383          File file = (File) value;
384          setIcon(fileView.getIcon(file));
385          setText(fileView.getName(file));
386          
387          if (isSelected)
388            {
389              setBackground(list.getSelectionBackground());
390              setForeground(list.getSelectionForeground());
391            }
392          else
393            {
394              setBackground(list.getBackground());
395              setForeground(list.getForeground());
396            }
397    
398          setEnabled(list.isEnabled());
399          setFont(list.getFont());
400          return this;
401        }
402      }
403    
404      /**
405     * A renderer for the files and directories in the file chooser.     * A renderer for the files and directories in the file chooser.
406     */     */
407    protected class FileRenderer extends DefaultListCellRenderer    protected class FileRenderer
408        extends DefaultListCellRenderer
409    {    {
410            
411      /**      /**
# Line 215  public class MetalFileChooserUI extends Line 434  public class MetalFileChooserUI extends
434        File f = (File) value;        File f = (File) value;
435        setText(v.getName(f));        setText(v.getName(f));
436        setIcon(v.getIcon(f));        setIcon(v.getIcon(f));
437          setOpaque(true);
438        if (isSelected)        if (isSelected)
439          {          {
440            setBackground(list.getSelectionBackground());            setBackground(list.getSelectionBackground());
# Line 249  public class MetalFileChooserUI extends Line 469  public class MetalFileChooserUI extends
469      protected FileFilter[] filters;      protected FileFilter[] filters;
470    
471      /** The index of the selected file filter. */      /** The index of the selected file filter. */
472      private int selectedIndex;      private Object selected;
473            
474      /**      /**
475       * Creates a new model.       * Creates a new model.
# Line 258  public class MetalFileChooserUI extends Line 478  public class MetalFileChooserUI extends
478      {      {
479        filters = new FileFilter[1];        filters = new FileFilter[1];
480        filters[0] = getAcceptAllFileFilter(getFileChooser());        filters[0] = getAcceptAllFileFilter(getFileChooser());
481        selectedIndex = 0;        selected = filters[0];
482      }      }
483            
484      /**      /**
# Line 270  public class MetalFileChooserUI extends Line 490  public class MetalFileChooserUI extends
490      {      {
491        if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))        if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
492          {          {
493            selectedIndex = -1;            JFileChooser fc = getFileChooser();
494            FileFilter selected = (FileFilter) e.getNewValue();            FileFilter[] choosableFilters = fc.getChoosableFileFilters();
495            for (int i = 0; i < filters.length; i++)            filters = choosableFilters;
496              if (filters[i].equals(selected))            fireContentsChanged(this, 0, filters.length);
497                selectedIndex = i;            selected = e.getNewValue();
498            fireContentsChanged(this, -1, -1);            fireContentsChanged(this, -1, -1);
499          }          }
500        else if (e.getPropertyName().equals(        else if (e.getPropertyName().equals(
# Line 291  public class MetalFileChooserUI extends Line 511  public class MetalFileChooserUI extends
511      /**      /**
512       * Sets the selected filter.       * Sets the selected filter.
513       *       *
514       * @param filter  the filter.       * @param filter  the filter (<code>null</code> ignored).
515       */       */
516      public void setSelectedItem(Object filter)      public void setSelectedItem(Object filter)
517      {      {
518        // change the filter in the file chooser and let the property change        if (filter != null)
519        // event trigger the change to the selected item        {
520        getFileChooser().setFileFilter((FileFilter) filter);            selected = filter;
521              fireContentsChanged(this, -1, -1);
522          }
523      }      }
524            
525      /**      /**
# Line 307  public class MetalFileChooserUI extends Line 529  public class MetalFileChooserUI extends
529       */       */
530      public Object getSelectedItem()      public Object getSelectedItem()
531      {      {
532        if (selectedIndex >= 0)        return selected;
         return filters[selectedIndex];  
       return null;  
533      }      }
534            
535      /**      /**
# Line 339  public class MetalFileChooserUI extends Line 559  public class MetalFileChooserUI extends
559    /**    /**
560     * A renderer for the items in the file filter combo box.     * A renderer for the items in the file filter combo box.
561     */     */
562    public class FilterComboBoxRenderer extends DefaultListCellRenderer    public class FilterComboBoxRenderer
563        extends DefaultListCellRenderer
564    {    {
565      /**      /**
566       * Creates a new renderer.       * Creates a new renderer.
# Line 359  public class MetalFileChooserUI extends Line 580  public class MetalFileChooserUI extends
580       * @param isSelected  is the item selected?       * @param isSelected  is the item selected?
581       * @param cellHasFocus  does the list cell have focus?       * @param cellHasFocus  does the list cell have focus?
582       *       *
583       * @return A component.       * @return This component as the renderer.
584       */       */
585      public Component getListCellRendererComponent(JList list, Object value,      public Component getListCellRendererComponent(JList list, Object value,
586          int index, boolean isSelected, boolean cellHasFocus)          int index, boolean isSelected, boolean cellHasFocus)
587      {      {
588          super.getListCellRendererComponent(list, value, index, isSelected,
589                                             cellHasFocus);
590        FileFilter filter = (FileFilter) value;        FileFilter filter = (FileFilter) value;
591        return super.getListCellRendererComponent(list, filter.getDescription(),        setText(filter.getDescription());
592                index, isSelected, cellHasFocus);        return this;
593      }      }
594    }    }
595    
596      /**
597       * A listener for selection events in the file list.
598       *
599       * @see #createListSelectionListener(JFileChooser)
600       */
601      class MetalFileChooserSelectionListener
602        implements ListSelectionListener
603      {
604        /**
605         * Creates a new <code>SelectionListener</code> object.
606         */
607        protected MetalFileChooserSelectionListener()
608        {
609          // Do nothing here.
610        }
611    
612        /**
613         * Makes changes to different properties when
614         * a value has changed in the filechooser's selection.
615         *
616         * @param e - the list selection event that occured.
617         */
618        public void valueChanged(ListSelectionEvent e)
619        {
620          File f = (File) fileList.getSelectedValue();
621          if (f == null)
622            return;
623          JFileChooser filechooser = getFileChooser();
624          if (! filechooser.isTraversable(f))
625            filechooser.setSelectedFile(f);
626          else
627            filechooser.setSelectedFile(null);
628        }
629      }
630    
631      /**
632       * A mouse listener for the {@link JFileChooser}.
633       * This listener is used for editing filenames.
634       */
635      protected class SingleClickListener
636        extends MouseAdapter
637      {
638        
639        /** Stores instance of the list */
640        JList list;
641        
642        /**
643         * Stores the current file that is being edited.
644         * It is null if nothing is currently being edited.
645         */
646        File editFile;
647        
648        /** The current file chooser. */
649        JFileChooser fc;
650        
651        /** The last file selected. */
652        Object lastSelected;
653        
654        /** The textfield used for editing. */
655        JTextField editField;
656        
657        /**
658         * Creates a new listener.
659         *
660         * @param list  the directory/file list.
661         */
662        public SingleClickListener(JList list)
663        {
664          this.list = list;
665          editFile = null;
666          fc = getFileChooser();
667          lastSelected = null;
668        }
669        
670        /**
671         * Receives notification of a mouse click event.
672         *
673         * @param e  the event.
674         */
675        public void mouseClicked(MouseEvent e)
676        {
677          if (e.getClickCount() == 1)
678            {
679              int index = list.locationToIndex(e.getPoint());
680              File[] sf = fc.getSelectedFiles();
681              if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
682                  && index >= 0 && editFile == null && list.isSelectedIndex(index))
683                {
684                  Object tmp = list.getModel().getElementAt(index);
685                  if (lastSelected != null && lastSelected.equals(tmp))
686                    editFile(index);
687                  lastSelected = tmp;
688                }
689              else if (editFile != null)
690                {
691                  completeEditing();
692                  editFile = null;
693                  lastSelected = null;
694                }
695            }
696        }
697        
698        /**
699         * Sets up the text editor for the current file.
700         *
701         * @param index -
702         *          the current index of the item in the list to be edited.
703         */
704        private void editFile(int index)
705        {
706          list.ensureIndexIsVisible(index);
707          editFile = (File) list.getModel().getElementAt(index);
708          if (editFile.canWrite())
709            {
710              Rectangle bounds = list.getCellBounds(index, index);
711              Icon icon = getFileView(fc).getIcon(editFile);
712              editField = new JTextField(editFile.getName());
713              // FIXME: add action listener for typing
714              // FIXME: painting for textfield is messed up when typing    
715              list.add(editField);
716              editField.requestFocus();
717              editField.selectAll();
718              
719              if (icon != null)
720                bounds.x += icon.getIconWidth() + 4;
721              editField.setBounds(bounds);
722            }
723          else
724            {
725              editField = null;
726              editFile = null;
727              lastSelected = null;
728            }
729        }
730        
731        /**
732         * Completes the editing.
733         */
734        private void completeEditing()
735        {
736          if (editField != null)
737            {
738              String text = editField.getText();
739              if (text != null && !text.equals(""))
740                editFile.renameTo(new File(text));
741              list.remove(editField);
742              list.revalidate();
743              list.repaint();
744            }
745        }
746      }
747    
748      /** The text for a label describing the directory combo box. */
749      private String directoryLabel;
750      
751      private JComboBox directoryComboBox;
752      
753    /** The model for the directory combo box. */    /** The model for the directory combo box. */
754    DirectoryComboBoxModel directoryModel;    DirectoryComboBoxModel directoryModel;
755        
756      /** The text for a label describing the file text field. */
757      private String fileLabel;
758      
759      /** The file name text field. */
760      private JTextField fileTextField;
761      
762      /** The text for a label describing the filter combo box. */
763      private String filterLabel;
764    
765      /**
766       * The top panel (contains the directory combo box and the control buttons).
767       */
768      private JPanel topPanel;
769      
770      /** A panel containing the control buttons ('up', 'home' etc.). */
771      private JPanel controls;
772    
773      /**
774       * The panel that contains the filename field and the filter combobox.
775       */
776      private JPanel bottomPanel;
777    
778      /**
779       * The panel that contains the 'Open' (or 'Save') and 'Cancel' buttons.
780       */
781      private JPanel buttonPanel;
782      
783      private JButton approveButton;
784      
785      /** The file list. */
786      private JList fileList;
787      
788      /** The panel containing the file list. */
789      private JPanel fileListPanel;
790      
791      /** The filter combo box model. */
792      private FilterComboBoxModel filterModel;
793    
794      /** The action map. */
795      private ActionMap actionMap;
796      
797    /**    /**
798     * A factory method that returns a UI delegate for the specified     * A factory method that returns a UI delegate for the specified
799     * component.     * component.
# Line 393  public class MetalFileChooserUI extends Line 814  public class MetalFileChooserUI extends
814    public MetalFileChooserUI(JFileChooser filechooser)    public MetalFileChooserUI(JFileChooser filechooser)
815    {    {
816      super(filechooser);      super(filechooser);
817        bottomPanel = new JPanel(new GridLayout(3, 2));
818        buttonPanel = new JPanel();
819      }
820    
821      public void installUI(JComponent c)
822      {
823        super.installUI(c);
824        actionMap = createActionMap();
825      }
826      
827      public void uninstallUI(JComponent c)
828      {
829        super.uninstallUI(c);
830        actionMap = null;
831      }
832      
833      /**
834       * Installs the sub-components of the file chooser.
835       *
836       * @param fc  the file chooser component.
837       */
838      public void installComponents(JFileChooser fc)
839      {
840        fc.setLayout(new BorderLayout());
841        topPanel = new JPanel(new BorderLayout());
842        topPanel.add(new JLabel(directoryLabel), BorderLayout.WEST);
843        this.controls = new JPanel();
844        addControlButtons();
845        
846        JPanel dirPanel = new JPanel(new VerticalMidLayout());
847        dirPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
848        directoryModel = createDirectoryComboBoxModel(fc);
849        directoryComboBox = new JComboBox(directoryModel);
850        directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
851        dirPanel.add(directoryComboBox);
852        topPanel.add(dirPanel);
853        topPanel.add(controls, BorderLayout.EAST);
854        fc.add(topPanel, BorderLayout.NORTH);
855        fileListPanel = createList(fc);
856        fc.add(fileListPanel);
857        JPanel bottomPanel = getBottomPanel();
858        filterModel = createFilterComboBoxModel();
859        JComboBox fileFilterCombo = new JComboBox(filterModel);
860        fileFilterCombo.setRenderer(createFilterComboBoxRenderer());
861        
862        fileTextField = new JTextField();
863        JPanel fileNamePanel = new JPanel(new VerticalMidLayout());
864        fileNamePanel.add(fileTextField);
865        JPanel row1 = new JPanel(new BorderLayout());
866        row1.add(new JLabel(this.fileLabel), BorderLayout.WEST);
867        row1.add(fileNamePanel);
868        bottomPanel.add(row1);
869        
870        JPanel filterPanel = new JPanel(new VerticalMidLayout());
871        filterPanel.add(fileFilterCombo);    
872        JPanel row2 = new JPanel(new BorderLayout());
873        row2.add(new JLabel(this.filterLabel), BorderLayout.WEST);
874        row2.add(filterPanel);
875        bottomPanel.add(row2);
876        JPanel buttonPanel = new JPanel(new ButtonLayout());
877        buttonPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 0));
878        
879        approveButton = new JButton(getApproveSelectionAction());
880        approveButton.setText(getApproveButtonText(fc));
881        approveButton.setToolTipText(getApproveButtonToolTipText(fc));
882        approveButton.setMnemonic(getApproveButtonMnemonic(fc));
883        buttonPanel.add(approveButton);
884        
885        JButton cancelButton = new JButton(getCancelSelectionAction());
886        cancelButton.setText(cancelButtonText);
887        cancelButton.setToolTipText(cancelButtonToolTipText);
888        cancelButton.setMnemonic(cancelButtonMnemonic);
889        buttonPanel.add(cancelButton);
890        bottomPanel.add(buttonPanel);
891        fc.add(bottomPanel, BorderLayout.SOUTH);
892      }
893      
894      /**
895       * Uninstalls the components added by
896       * {@link #installComponents(JFileChooser)}.
897       *
898       * @param fc  the file chooser.
899       */
900      public void uninstallComponents(JFileChooser fc)
901      {
902        fc.remove(bottomPanel);
903        bottomPanel = null;
904        fc.remove(fileListPanel);
905        fileListPanel = null;
906        fc.remove(topPanel);
907        topPanel = null;
908        
909        directoryModel = null;
910        fileTextField = null;
911        directoryComboBox = null;
912      }
913      
914      /**
915       * Returns the panel that contains the 'Open' (or 'Save') and 'Cancel'
916       * buttons.
917       *
918       * @return The panel.
919       */
920      protected JPanel getButtonPanel()
921      {
922        return buttonPanel;    
923      }
924      
925      /**
926       * Creates and returns a new panel that will be used for the controls at
927       * the bottom of the file chooser.
928       *
929       * @return A new panel.
930       */
931      protected JPanel getBottomPanel()
932      {
933        if (bottomPanel == null)
934          bottomPanel = new JPanel(new GridLayout(3, 2));
935        return bottomPanel;
936      }
937      
938      /**
939       * Fetches localised strings for use by the labels and buttons on the
940       * file chooser.
941       *
942       * @param fc  the file chooser.
943       */
944      protected void installStrings(JFileChooser fc)
945      {
946         super.installStrings(fc);
947         directoryLabel = "Look In: ";
948         fileLabel = "File Name: ";
949         filterLabel = "Files of Type: ";
950        
951         this.cancelButtonMnemonic = 0;
952         this.cancelButtonText = "Cancel";
953         this.cancelButtonToolTipText = "Abort file chooser dialog";
954        
955         this.directoryOpenButtonMnemonic = 0;
956         this.directoryOpenButtonText = "Open";
957         this.directoryOpenButtonToolTipText = "Open selected directory";
958        
959         this.helpButtonMnemonic = 0;
960         this.helpButtonText = "Help";
961         this.helpButtonToolTipText = "Filechooser help";
962        
963         this.openButtonMnemonic = 0;
964         this.openButtonText = "Open";
965         this.openButtonToolTipText = "Open selected file";
966        
967         this.saveButtonMnemonic = 0;
968         this.saveButtonText = "Save";
969         this.saveButtonToolTipText = "Save selected file";
970        
971         this.updateButtonMnemonic = 0;
972         this.updateButtonText = "Update";
973         this.updateButtonToolTipText = "Update directory listing";  
974      }
975      
976      /**
977       * Installs the listeners required.
978       *
979       * @param fc  the file chooser.
980       */
981      protected void installListeners(JFileChooser fc)
982      {
983        directoryComboBox.setAction(new DirectoryComboBoxAction());
984        fileList.addListSelectionListener(createListSelectionListener(fc));
985        fileList.addMouseListener(this.createDoubleClickListener(fc, fileList));
986        fileList.addMouseListener(new SingleClickListener(fileList));
987        fc.addPropertyChangeListener(filterModel);
988        super.installListeners(fc);
989      }
990      
991      protected void uninstallListeners(JFileChooser fc)
992      {
993        super.uninstallListeners(fc);
994        fc.removePropertyChangeListener(filterModel);
995      }
996      
997      protected ActionMap getActionMap()
998      {
999        if (actionMap == null)
1000          actionMap = createActionMap();
1001        return actionMap;
1002      }
1003      
1004      /**
1005       * Creates and returns an action map.
1006       *
1007       * @return The action map.
1008       */
1009      protected ActionMap createActionMap()
1010      {
1011        ActionMap map = new ActionMap();
1012        map.put("approveSelection", getApproveSelectionAction());
1013        map.put("cancelSelection", null);  // FIXME: implement this one
1014        map.put("Go Up", getChangeToParentDirectoryAction());
1015        return map;
1016      }
1017    
1018      /**
1019       * Creates a panel containing a list of files.
1020       *
1021       * @param fc  the file chooser.
1022       *
1023       * @return A panel.
1024       */
1025      protected JPanel createList(JFileChooser fc)
1026      {
1027        JPanel panel = new JPanel(new BorderLayout());
1028        fileList = new JList(getModel());
1029        fileList.setLayoutOrientation(JList.VERTICAL_WRAP);
1030        fileList.setVisibleRowCount(0);
1031        fileList.setCellRenderer(new FileRenderer());
1032        panel.add(new JScrollPane(fileList));
1033        return panel;    
1034      }
1035      
1036      /**
1037       * Creates a panel containing a table within a scroll pane.
1038       *
1039       * @param fc  the file chooser.
1040       *
1041       * @return The details view.
1042       */
1043      protected JPanel createDetailsView(JFileChooser fc)
1044      {
1045        // FIXME: implement this.  The details view is a panel containing a table
1046        // inside a JScrollPane - it gets displayed when the user clicks on the
1047        // "details" button.
1048        return new JPanel();
1049      }
1050      
1051      /**
1052       * Creates a listener that monitors selections in the directory/file list
1053       * and keeps the {@link JFileChooser} component up to date.
1054       *
1055       * @param fc  the file chooser.
1056       *
1057       * @return The listener.
1058       *
1059       * @see #installListeners(JFileChooser)
1060       */
1061      public ListSelectionListener createListSelectionListener(JFileChooser fc)
1062      {
1063        return new MetalFileChooserSelectionListener();
1064    }    }
1065        
1066    /**    /**
1067       * Returns the preferred size for the file chooser component.
1068       *
1069       * @return The preferred size.
1070       */
1071      public Dimension getPreferredSize(JComponent c)
1072      {
1073        // FIXME: not likely to be a fixed value
1074        return new Dimension(500, 326);
1075      }
1076      
1077      /**
1078       * Returns the minimum size for the file chooser component.
1079       *
1080       * @return The minimum size.
1081       */
1082      public Dimension getMinimumSize(JComponent c)
1083      {
1084        // FIXME: not likely to be a fixed value
1085        return new Dimension(506, 326);      
1086      }
1087      
1088      /**
1089       * Returns the maximum size for the file chooser component.
1090       *
1091       * @return The maximum size.
1092       */
1093      public Dimension getMaximumSize(JComponent c)
1094      {
1095        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1096      }
1097      
1098      /**
1099       * Creates a property change listener that monitors the {@link JFileChooser}
1100       * for property change events and updates the component display accordingly.
1101       *
1102       * @param fc  the file chooser.
1103       *
1104       * @return The property change listener.
1105       *
1106       * @see #installListeners(JFileChooser)
1107       */
1108      public PropertyChangeListener createPropertyChangeListener(JFileChooser fc)
1109      {
1110        return new MetalFileChooserPropertyChangeListener();
1111      }
1112    
1113      /**
1114     * Creates and returns a new instance of {@link DirectoryComboBoxModel}.     * Creates and returns a new instance of {@link DirectoryComboBoxModel}.
1115     *     *
1116     * @return A new instance of {@link DirectoryComboBoxModel}.     * @return A new instance of {@link DirectoryComboBoxModel}.
# Line 407  public class MetalFileChooserUI extends Line 1122  public class MetalFileChooserUI extends
1122    }    }
1123    
1124    /**    /**
1125       * Creates a new instance of the renderer used in the directory
1126       * combo box.
1127       *
1128       * @param fc  the file chooser.
1129       *
1130       * @return The renderer.
1131       */
1132      protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(
1133              JFileChooser fc)
1134      {
1135        return new DirectoryComboBoxRenderer(fc);
1136      }
1137    
1138      /**
1139     * Creates and returns a new instance of {@link FilterComboBoxModel}.     * Creates and returns a new instance of {@link FilterComboBoxModel}.
1140     *     *
1141     * @return A new instance of {@link FilterComboBoxModel}.     * @return A new instance of {@link FilterComboBoxModel}.
# Line 427  public class MetalFileChooserUI extends Line 1156  public class MetalFileChooserUI extends
1156      return new FilterComboBoxRenderer();      return new FilterComboBoxRenderer();
1157    }    }
1158    
1159      /**
1160       * Adds the control buttons ('up', 'home' etc.) to the panel.
1161       */
1162      protected void addControlButtons()
1163      {
1164        JButton upButton = new JButton(getChangeToParentDirectoryAction());
1165        upButton.setText(null);
1166        upButton.setIcon(this.upFolderIcon);
1167        upButton.setMargin(new Insets(0, 0, 0, 0));
1168        controls.add(upButton);
1169        
1170        JButton homeButton = new JButton(getGoHomeAction());
1171        homeButton.setText(null);
1172        homeButton.setIcon(this.homeFolderIcon);
1173        homeButton.setMargin(new Insets(0, 0, 0, 0));
1174        controls.add(homeButton);
1175        
1176        JButton newFolderButton = new JButton(getNewFolderAction());
1177        newFolderButton.setText(null);
1178        newFolderButton.setIcon(this.newFolderIcon);
1179        newFolderButton.setMargin(new Insets(0, 0, 0, 0));
1180        controls.add(newFolderButton);
1181        
1182        JToggleButton listButton = new JToggleButton();
1183        listButton.setIcon(this.listViewIcon);
1184        listButton.setMargin(new Insets(0, 0, 0, 0));
1185        // FIXME: this button needs an action that handles a click
1186        controls.add(listButton);
1187        
1188        JToggleButton detailButton = new JToggleButton(this.detailsViewIcon);
1189        detailButton.setMargin(new Insets(0, 0, 0, 0));
1190        // FIXME: this button needs an action that handles a click
1191        controls.add(detailButton);
1192    
1193        ButtonGroup buttonGroup = new ButtonGroup();
1194        buttonGroup.add(listButton);
1195        buttonGroup.add(detailButton);
1196      }
1197      
1198      protected void removeControlButtons()
1199      {
1200        controls.removeAll();
1201      }
1202      
1203      public void ensureFileIsVisible(JFileChooser fc, File f)
1204      {
1205        // FIXME: do something here - probably this figures out whether the
1206        // list or table view is current, and forwards the request to the
1207        // appropriate one...
1208        super.ensureFileIsVisible(fc, f);
1209      }
1210      
1211      public void rescanCurrentDirectory(JFileChooser fc)
1212      {
1213        // FIXME: this will need to take into account whether the list view or
1214        // the table view is current
1215        directoryModel.setSelectedItem(fc.getCurrentDirectory());
1216        getModel().validateFileCache();
1217        fileList.revalidate();
1218      }
1219      
1220      /**
1221       * Returns the file name in the text field.
1222       *
1223       * @return The file name.
1224       */
1225      public String getFileName()
1226      {
1227        String result = null;
1228        if (fileTextField != null)
1229          result = fileTextField.getText();
1230        return result;
1231      }
1232      
1233      /**
1234       * Sets the file name in the text field.
1235       *
1236       * @param filename  the file name.
1237       */
1238      public void setFileName(String filename)
1239      {
1240        fileTextField.setText(filename);
1241      }
1242    
1243      protected void setDirectorySelected(boolean directorySelected)
1244      {
1245        // FIXME: do something here
1246        super.setDirectorySelected(directorySelected);
1247      }
1248      
1249      public String getDirectoryName()
1250      {
1251        // FIXME: do something here
1252        return super.getDirectoryName();      
1253      }
1254    
1255      public void setDirectoryName(String dirname)
1256      {
1257        // FIXME: do something here
1258        super.setDirectoryName(dirname);    
1259      }
1260      
1261      public void valueChanged(ListSelectionEvent e)
1262      {
1263        // FIXME: implement
1264      }
1265      
1266      /**
1267       * Returns the approve button.
1268       *
1269       * @return The approve button.
1270       */
1271      protected JButton getApproveButton(JFileChooser fc)
1272      {
1273        return approveButton;
1274      }
1275    
1276      /**
1277       * A layout manager that is used to arrange the subcomponents of the
1278       * {@link JFileChooser}.
1279       */
1280      class VerticalMidLayout implements LayoutManager
1281      {
1282        /**
1283         * Performs the layout.
1284         *
1285         * @param parent  the container.
1286         */
1287        public void layoutContainer(Container parent)
1288        {
1289          int count = parent.getComponentCount();
1290          if (count > 0)
1291            {
1292              Insets insets = parent.getInsets();
1293              Component c = parent.getComponent(0);
1294              Dimension prefSize = c.getPreferredSize();
1295              int h = parent.getHeight() - insets.top - insets.bottom;
1296              int adj = Math.max(0, (h - prefSize.height) / 2);
1297              c.setBounds(insets.left, insets.top + adj, parent.getWidth()
1298                  - insets.left - insets.right,
1299                  (int) Math.min(prefSize.getHeight(), h));
1300            }
1301        }
1302        
1303        /**
1304         * Returns the minimum layout size.
1305         *
1306         * @param parent  the container.
1307         *
1308         * @return The minimum layout size.
1309         */
1310        public Dimension minimumLayoutSize(Container parent)
1311        {
1312          return preferredLayoutSize(parent);
1313        }
1314        
1315        /**
1316         * Returns the preferred layout size.
1317         *
1318         * @param parent  the container.
1319         *
1320         * @return The preferred layout size.
1321         */
1322        public Dimension preferredLayoutSize(Container parent)
1323        {
1324          if (parent.getComponentCount() > 0)
1325            {
1326              return parent.getComponent(0).getPreferredSize();
1327            }
1328          else return null;
1329        }
1330        
1331        /**
1332         * This layout manager does not need to track components, so this
1333         * method does nothing.
1334         *
1335         * @param name  the name the component is associated with.
1336         * @param component  the component.
1337         */
1338        public void addLayoutComponent(String name, Component component)
1339        {
1340          // do nothing
1341        }
1342        
1343        /**
1344         * This layout manager does not need to track components, so this
1345         * method does nothing.
1346         *
1347         * @param component  the component.
1348         */
1349        public void removeLayoutComponent(Component component) {
1350          // do nothing
1351        }
1352      }
1353    
1354      /**
1355       * A layout manager that is used to arrange buttons for the
1356       * {@link JFileChooser}.
1357       */
1358      class ButtonLayout implements LayoutManager
1359      {
1360        static final int GAP = 4;
1361          
1362        /**
1363         * Performs the layout.
1364         *
1365         * @param parent  the container.
1366         */
1367        public void layoutContainer(Container parent)
1368        {
1369          int count = parent.getComponentCount();
1370          if (count > 0)
1371            {
1372              // first find the widest button
1373              int maxW = 0;
1374              for (int i = 0; i < count; i++)
1375                {
1376                  Component c = parent.getComponent(i);
1377                  Dimension prefSize = c.getPreferredSize();
1378                  maxW = Math.max(prefSize.width, maxW);
1379                }
1380      
1381              // then position the buttons
1382              Insets insets = parent.getInsets();
1383              int availableH = parent.getHeight() - insets.top - insets.bottom;
1384              int currentX = parent.getWidth() - insets.right;
1385              for (int i = count - 1; i >= 0; i--)
1386                {
1387                  Component c = parent.getComponent(i);
1388                  Dimension prefSize = c.getPreferredSize();      
1389                  int adj = Math.max(0, (availableH - prefSize.height) / 2);
1390                  currentX = currentX - prefSize.width;
1391                  c.setBounds(currentX, insets.top + adj, prefSize.width,
1392                      (int) Math.min(prefSize.getHeight(), availableH));
1393                  currentX = currentX - GAP;
1394                }
1395            }
1396        }
1397        
1398        /**
1399         * Returns the minimum layout size.
1400         *
1401         * @param parent  the container.
1402         *
1403         * @return The minimum layout size.
1404         */
1405        public Dimension minimumLayoutSize(Container parent)
1406        {
1407          return preferredLayoutSize(parent);
1408        }
1409        
1410        /**
1411         * Returns the preferred layout size.
1412         *
1413         * @param parent  the container.
1414         *
1415         * @return The preferred layout size.
1416         */
1417        public Dimension preferredLayoutSize(Container parent)
1418        {
1419          Insets insets = parent.getInsets();
1420          int maxW = 0;
1421          int maxH = 0;
1422          int count = parent.getComponentCount();
1423          if (count > 0)
1424            {
1425              for (int i = 0; i < count; i++)
1426                {
1427                  Component c = parent.getComponent(i);
1428                  Dimension d = c.getPreferredSize();
1429                  maxW = Math.max(d.width, maxW);
1430                  maxH = Math.max(d.height, maxH);
1431                }
1432            }
1433          return new Dimension(maxW * count + GAP * (count - 1) + insets.left
1434                  + insets.right, maxH + insets.top + insets.bottom);
1435        }
1436        
1437        /**
1438         * This layout manager does not need to track components, so this
1439         * method does nothing.
1440         *
1441         * @param name  the name the component is associated with.
1442         * @param component  the component.
1443         */
1444        public void addLayoutComponent(String name, Component component)
1445        {
1446          // do nothing
1447        }
1448        
1449        /**
1450         * This layout manager does not need to track components, so this
1451         * method does nothing.
1452         *
1453         * @param component  the component.
1454         */
1455        public void removeLayoutComponent(Component component) {
1456          // do nothing
1457        }
1458      }
1459    
1460  }  }

Legend:
Removed from v.1.3.2.1  
changed lines
  Added in v.1.3.2.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26