OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [plaf/] [metal/] [MetalFileChooserUI.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* MetalFileChooserUI.java --
2
   Copyright (C) 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing.plaf.metal;
40
 
41
import java.awt.BorderLayout;
42
import java.awt.Component;
43
import java.awt.Container;
44
import java.awt.Dimension;
45
import java.awt.Graphics;
46
import java.awt.GridLayout;
47
import java.awt.Insets;
48
import java.awt.LayoutManager;
49
import java.awt.Rectangle;
50
import java.awt.Window;
51
import java.awt.event.ActionEvent;
52
import java.awt.event.ActionListener;
53
import java.awt.event.MouseAdapter;
54
import java.awt.event.MouseEvent;
55
import java.awt.event.MouseListener;
56
import java.beans.PropertyChangeEvent;
57
import java.beans.PropertyChangeListener;
58
import java.io.File;
59
import java.text.DateFormat;
60
import java.text.NumberFormat;
61
import java.util.Date;
62
import java.util.List;
63
 
64
import javax.swing.AbstractAction;
65
import javax.swing.AbstractListModel;
66
import javax.swing.ActionMap;
67
import javax.swing.BorderFactory;
68
import javax.swing.ButtonGroup;
69
import javax.swing.ComboBoxModel;
70
import javax.swing.DefaultListCellRenderer;
71
import javax.swing.Icon;
72
import javax.swing.JButton;
73
import javax.swing.JComboBox;
74
import javax.swing.JComponent;
75
import javax.swing.JDialog;
76
import javax.swing.JFileChooser;
77
import javax.swing.JLabel;
78
import javax.swing.JList;
79
import javax.swing.JPanel;
80
import javax.swing.JScrollPane;
81
import javax.swing.JTable;
82
import javax.swing.JTextField;
83
import javax.swing.JToggleButton;
84
import javax.swing.ListModel;
85
import javax.swing.ListSelectionModel;
86
import javax.swing.SwingUtilities;
87
import javax.swing.UIManager;
88
import javax.swing.event.ListSelectionEvent;
89
import javax.swing.event.ListSelectionListener;
90
import javax.swing.filechooser.FileFilter;
91
import javax.swing.filechooser.FileSystemView;
92
import javax.swing.filechooser.FileView;
93
import javax.swing.plaf.ComponentUI;
94
import javax.swing.plaf.basic.BasicFileChooserUI;
95
import javax.swing.table.DefaultTableCellRenderer;
96
import javax.swing.table.DefaultTableModel;
97
 
98
 
99
/**
100
 * A UI delegate for the {@link JFileChooser} component.  This class is only
101
 * partially implemented and is not usable yet.
102
 */
103
public class MetalFileChooserUI
104
  extends BasicFileChooserUI
105
{
106
 
107
  /**
108
   * A renderer for the files and directories in the file chooser table.
109
   */
110
  class TableFileRenderer
111
    extends DefaultTableCellRenderer
112
  {
113
 
114
    /**
115
     * Creates a new renderer.
116
     */
117
    public TableFileRenderer()
118
    {
119
      super();
120
    }
121
 
122
    /**
123
     * Returns a component that can render the specified value.
124
     *
125
     * @param table  the table
126
     * @param value  the string value of the cell
127
     * @param isSelected  is the item selected?
128
     * @param hasFocus  does the item have the focus?
129
     * @param row  the row
130
     * @param column  the column
131
     *
132
     * @return The renderer.
133
     */
134
    public Component getTableCellRendererComponent(JTable table, Object value,
135
        boolean isSelected, boolean hasFocus, int row, int column)
136
    {
137
      if (column == 0)
138
        {
139
          FileView v = getFileView(getFileChooser());
140
          ListModel lm = fileList.getModel();
141
          if (row < lm.getSize())
142
            setIcon(v.getIcon((File) lm.getElementAt(row)));
143
        }
144
      else
145
        setIcon(null);
146
 
147
      setText(value.toString());
148
      setOpaque(true);
149
      setEnabled(table.isEnabled());
150
      setFont(fileList.getFont());
151
 
152
      if (startEditing && column == 0 || !isSelected)
153
        {
154
          setBackground(table.getBackground());
155
          setForeground(table.getForeground());
156
        }
157
      else
158
        {
159
          setBackground(table.getSelectionBackground());
160
          setForeground(table.getSelectionForeground());
161
        }
162
 
163
      if (hasFocus)
164
        setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
165
      else
166
        setBorder(noFocusBorder);
167
 
168
      return this;
169
    }
170
  }
171
 
172
  /**
173
   * ActionListener for the list view.
174
   */
175
  class ListViewActionListener implements ActionListener
176
  {
177
 
178
    /**
179
     * This method is invoked when an action occurs.
180
     *
181
     * @param e -
182
     *          the <code>ActionEvent</code> that occurred
183
     */
184
    public void actionPerformed(ActionEvent e)
185
    {
186
      if (!listView)
187
        {
188
          int[] index = fileTable.getSelectedRows();
189
          listView = true;
190
          JFileChooser fc = getFileChooser();
191
          fc.remove(fileTablePanel);
192
          createList(fc);
193
 
194
          fileList.getSelectionModel().clearSelection();
195
          if (index.length > 0)
196
              for (int i = 0; i < index.length; i++)
197
                fileList.getSelectionModel().addSelectionInterval(index[i], index[i]);
198
 
199
          fc.add(fileListPanel, BorderLayout.CENTER);
200
          fc.revalidate();
201
          fc.repaint();
202
        }
203
    }
204
  }
205
 
206
  /**
207
   * ActionListener for the details view.
208
   */
209
  class DetailViewActionListener implements ActionListener
210
  {
211
 
212
    /**
213
     * This method is invoked when an action occurs.
214
     *
215
     * @param e -
216
     *          the <code>ActionEvent</code> that occurred
217
     */
218
    public void actionPerformed(ActionEvent e)
219
    {
220
      if (listView)
221
        {
222
          int[] index = fileList.getSelectedIndices();
223
          JFileChooser fc = getFileChooser();
224
          listView = false;
225
          fc.remove(fileListPanel);
226
 
227
          if (fileTable == null)
228
            createDetailsView(fc);
229
          else
230
            updateTable();
231
 
232
          fileTable.getSelectionModel().clearSelection();
233
          if (index.length > 0)
234
            {
235
              for (int i = 0; i < index.length; i++)
236
                fileTable.getSelectionModel().addSelectionInterval(index[i], index[i]);
237
            }
238
 
239
          fc.add(fileTablePanel, BorderLayout.CENTER);
240
          fc.revalidate();
241
          fc.repaint();
242
        }
243
    }
244
  }
245
 
246
  /**
247
   * A property change listener.
248
   */
249
  class MetalFileChooserPropertyChangeListener
250
    implements PropertyChangeListener
251
  {
252
    /**
253
     * Default constructor.
254
     */
255
    public MetalFileChooserPropertyChangeListener()
256
    {
257
    }
258
 
259
    /**
260
     * Handles a property change event.
261
     *
262
     * @param e  the event.
263
     */
264
    public void propertyChange(PropertyChangeEvent e)
265
    {
266
      JFileChooser filechooser = getFileChooser();
267
 
268
      String n = e.getPropertyName();
269
      if (n.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY))
270
        {
271
          int mode = -1;
272
          if (filechooser.isMultiSelectionEnabled())
273
            mode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
274
          else
275
            mode = ListSelectionModel.SINGLE_SELECTION;
276
 
277
          if (listView)
278
            fileList.setSelectionMode(mode);
279
          else
280
            fileTable.setSelectionMode(mode);
281
        }
282
      else if (n.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY))
283
        {
284
          File file = filechooser.getSelectedFile();
285
 
286
          if (file != null
287
              && filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
288
            {
289
              if (file.isDirectory() && filechooser.isTraversable(file))
290
                {
291
                  directoryLabel = look;
292
                  dirLabel.setText(directoryLabel);
293
                  filechooser.setApproveButtonText(openButtonText);
294
                  filechooser.setApproveButtonToolTipText(openButtonToolTipText);
295
                }
296
              else if (file.isFile())
297
                {
298
                  directoryLabel = save;
299
                  dirLabel.setText(directoryLabel);
300
                  filechooser.setApproveButtonText(saveButtonText);
301
                  filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
302
                }
303
            }
304
 
305
          if (file == null)
306
            setFileName(null);
307
          else if (file.isFile() || filechooser.getFileSelectionMode()
308
                   != JFileChooser.FILES_ONLY)
309
            setFileName(file.getName());
310
          int index = -1;
311
          index = getModel().indexOf(file);
312
          if (index >= 0)
313
            {
314
              if (listView)
315
                {
316
                  fileList.setSelectedIndex(index);
317
                  fileList.ensureIndexIsVisible(index);
318
                  fileList.revalidate();
319
                  fileList.repaint();
320
                }
321
              else
322
                {
323
                  fileTable.getSelectionModel().addSelectionInterval(index, index);
324
                  fileTable.scrollRectToVisible(fileTable.getCellRect(index, 0, true));
325
                  fileTable.revalidate();
326
                  fileTable.repaint();
327
                }
328
            }
329
        }
330
 
331
      else if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY))
332
        {
333
          if (listView)
334
            {
335
              fileList.clearSelection();
336
              fileList.revalidate();
337
              fileList.repaint();
338
            }
339
          else
340
            {
341
              fileTable.clearSelection();
342
              fileTable.revalidate();
343
              fileTable.repaint();
344
            }
345
 
346
          setDirectorySelected(false);
347
          File currentDirectory = filechooser.getCurrentDirectory();
348
          setDirectory(currentDirectory);
349
          boolean hasParent = currentDirectory.getParentFile() != null;
350
          getChangeToParentDirectoryAction().setEnabled(hasParent);
351
        }
352
 
353
      else if (n.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
354
        {
355
          filterModel.propertyChange(e);
356
        }
357
      else if (n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
358
        {
359
          filterModel.propertyChange(e);
360
        }
361
      else if (n.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)
362
                 || n.equals(JFileChooser.DIALOG_TITLE_CHANGED_PROPERTY))
363
        {
364
          Window owner = SwingUtilities.windowForComponent(filechooser);
365
          if (owner instanceof JDialog)
366
            ((JDialog) owner).setTitle(getDialogTitle(filechooser));
367
          approveButton.setText(getApproveButtonText(filechooser));
368
          approveButton.setToolTipText(
369
                  getApproveButtonToolTipText(filechooser));
370
          approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
371
        }
372
 
373
      else if (n.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY))
374
        approveButton.setText(getApproveButtonText(filechooser));
375
 
376
      else if (n.equals(
377
              JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY))
378
        approveButton.setToolTipText(getApproveButtonToolTipText(filechooser));
379
 
380
      else if (n.equals(JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY))
381
        approveButton.setMnemonic(getApproveButtonMnemonic(filechooser));
382
 
383
      else if (n.equals(
384
              JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY))
385
        {
386
          if (filechooser.getControlButtonsAreShown())
387
            {
388
              topPanel.add(controls, BorderLayout.EAST);
389
            }
390
          else
391
            topPanel.remove(controls);
392
          topPanel.revalidate();
393
          topPanel.repaint();
394
          topPanel.doLayout();
395
        }
396
 
397
      else if (n.equals(
398
              JFileChooser.ACCEPT_ALL_FILE_FILTER_USED_CHANGED_PROPERTY))
399
        {
400
          if (filechooser.isAcceptAllFileFilterUsed())
401
            filechooser.addChoosableFileFilter(
402
                    getAcceptAllFileFilter(filechooser));
403
          else
404
            filechooser.removeChoosableFileFilter(
405
                    getAcceptAllFileFilter(filechooser));
406
        }
407
 
408
      else if (n.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY))
409
        {
410
          JComponent old = (JComponent) e.getOldValue();
411
          if (old != null)
412
            getAccessoryPanel().remove(old);
413
          JComponent newval = (JComponent) e.getNewValue();
414
          if (newval != null)
415
            getAccessoryPanel().add(newval);
416
        }
417
 
418
      if (n.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)
419
          || n.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)
420
          || n.equals(JFileChooser.FILE_HIDING_CHANGED_PROPERTY))
421
        {
422
          // Remove editing component
423
          if (fileTable != null)
424
            fileTable.removeAll();
425
          if (fileList != null)
426
            fileList.removeAll();
427
          startEditing = false;
428
 
429
          // Set text on button back to original.
430
          if (filechooser.getDialogType() == JFileChooser.SAVE_DIALOG)
431
            {
432
              directoryLabel = save;
433
              dirLabel.setText(directoryLabel);
434
              filechooser.setApproveButtonText(saveButtonText);
435
              filechooser.setApproveButtonToolTipText(saveButtonToolTipText);
436
            }
437
 
438
          rescanCurrentDirectory(filechooser);
439
        }
440
 
441
      filechooser.revalidate();
442
      filechooser.repaint();
443
    }
444
  }
445
 
446
  /**
447
   * A combo box model containing the selected directory and all its parent
448
   * directories.
449
   */
450
  protected class DirectoryComboBoxModel
451
    extends AbstractListModel
452
    implements ComboBoxModel
453
  {
454
    /** Storage for the items in the model. */
455
    private List items;
456
 
457
    /** The index of the selected item. */
458
    private int selectedIndex;
459
 
460
    /**
461
     * Creates a new model.
462
     */
463
    public DirectoryComboBoxModel()
464
    {
465
      items = new java.util.ArrayList();
466
      selectedIndex = -1;
467
    }
468
 
469
    /**
470
     * Returns the number of items in the model.
471
     *
472
     * @return The number of items in the model.
473
     */
474
    public int getSize()
475
    {
476
      return items.size();
477
    }
478
 
479
    /**
480
     * Returns the item at the specified index.
481
     *
482
     * @param index  the item index.
483
     *
484
     * @return The item.
485
     */
486
    public Object getElementAt(int index)
487
    {
488
      return items.get(index);
489
    }
490
 
491
    /**
492
     * Returns the depth of the item at the given <code>index</code>.
493
     *
494
     * @param index  the item index.
495
     *
496
     * @return The depth.
497
     */
498
    public int getDepth(int index)
499
    {
500
      return Math.max(index, 0);
501
    }
502
 
503
    /**
504
     * Returns the selected item, or <code>null</code> if no item is selected.
505
     *
506
     * @return The selected item, or <code>null</code>.
507
     */
508
    public Object getSelectedItem()
509
    {
510
      if (selectedIndex >= 0)
511
        return items.get(selectedIndex);
512
      else
513
        return null;
514
    }
515
 
516
    /**
517
     * Sets the selected item.  This clears all the directories from the
518
     * existing list, and repopulates it with the new selected directory
519
     * and all its parent directories.
520
     *
521
     * @param selectedDirectory  the selected directory.
522
     */
523
    public void setSelectedItem(Object selectedDirectory)
524
    {
525
      items.clear();
526
      FileSystemView fsv = getFileChooser().getFileSystemView();
527
      File parent = (File) selectedDirectory;
528
      while (parent != null)
529
        {
530
          items.add(0, parent);
531
          parent = fsv.getParentDirectory(parent);
532
        }
533
      selectedIndex = items.indexOf(selectedDirectory);
534
      fireContentsChanged(this, 0, items.size() - 1);
535
    }
536
 
537
  }
538
 
539
  /**
540
   * Handles changes to the selection in the directory combo box.
541
   */
542
  protected class DirectoryComboBoxAction
543
    extends AbstractAction
544
  {
545
    /**
546
     * Creates a new action.
547
     */
548
    protected DirectoryComboBoxAction()
549
    {
550
      // Nothing to do here.
551
    }
552
 
553
    /**
554
     * Handles the action event.
555
     *
556
     * @param e  the event.
557
     */
558
    public void actionPerformed(ActionEvent e)
559
    {
560
      JFileChooser fc = getFileChooser();
561
      fc.setCurrentDirectory((File) directoryModel.getSelectedItem());
562
    }
563
  }
564
 
565
  /**
566
   * A renderer for the items in the directory combo box.
567
   */
568
  class DirectoryComboBoxRenderer
569
    extends DefaultListCellRenderer
570
  {
571
    /**
572
     * This is the icon that is displayed in the combobox. This wraps
573
     * the standard icon and adds indendation.
574
     */
575
    private IndentIcon indentIcon;
576
 
577
    /**
578
     * Creates a new renderer.
579
     */
580
    public DirectoryComboBoxRenderer(JFileChooser fc)
581
    {
582
      indentIcon = new IndentIcon();
583
    }
584
 
585
    /**
586
     * Returns a component that can be used to paint the given value within
587
     * the list.
588
     *
589
     * @param list  the list.
590
     * @param value  the value (a {@link File}).
591
     * @param index  the item index.
592
     * @param isSelected  is the item selected?
593
     * @param cellHasFocus  does the list cell have focus?
594
     *
595
     * @return The list cell renderer.
596
     */
597
    public Component getListCellRendererComponent(JList list, Object value,
598
                                                  int index,
599
                                                  boolean isSelected,
600
                                                  boolean cellHasFocus)
601
    {
602
      super.getListCellRendererComponent(list, value, index, isSelected,
603
                                         cellHasFocus);
604
      File file = (File) value;
605
      setText(getFileChooser().getName(file));
606
 
607
      // Install indented icon.
608
      Icon icon = getFileChooser().getIcon(file);
609
      indentIcon.setIcon(icon);
610
      int depth = directoryModel.getDepth(index);
611
      indentIcon.setDepth(depth);
612
      setIcon(indentIcon);
613
 
614
      return this;
615
    }
616
  }
617
 
618
  /**
619
   * An icon that wraps another icon and adds indentation.
620
   */
621
  class IndentIcon
622
    implements Icon
623
  {
624
 
625
    /**
626
     * The indentation level.
627
     */
628
    private static final int INDENT = 10;
629
 
630
    /**
631
     * The wrapped icon.
632
     */
633
    private Icon icon;
634
 
635
    /**
636
     * The current depth.
637
     */
638
    private int depth;
639
 
640
    /**
641
     * Sets the icon to be wrapped.
642
     *
643
     * @param i the icon
644
     */
645
    void setIcon(Icon i)
646
    {
647
      icon = i;
648
    }
649
 
650
    /**
651
     * Sets the indentation depth.
652
     *
653
     * @param d the depth to set
654
     */
655
    void setDepth(int d)
656
    {
657
      depth = d;
658
    }
659
 
660
    public int getIconHeight()
661
    {
662
      return icon.getIconHeight();
663
    }
664
 
665
    public int getIconWidth()
666
    {
667
      return icon.getIconWidth() + depth * INDENT;
668
    }
669
 
670
    public void paintIcon(Component c, Graphics g, int x, int y)
671
    {
672
      icon.paintIcon(c, g, x + depth * INDENT, y);
673
    }
674
 
675
  }
676
 
677
  /**
678
   * A renderer for the files and directories in the file chooser.
679
   */
680
  protected class FileRenderer
681
    extends DefaultListCellRenderer
682
  {
683
 
684
    /**
685
     * Creates a new renderer.
686
     */
687
    protected FileRenderer()
688
    {
689
      // Nothing to do here.
690
    }
691
 
692
    /**
693
     * Returns a component that can render the specified value.
694
     *
695
     * @param list  the list.
696
     * @param value  the value (a {@link File}).
697
     * @param index  the index.
698
     * @param isSelected  is the item selected?
699
     * @param cellHasFocus  does the item have the focus?
700
     *
701
     * @return The renderer.
702
     */
703
    public Component getListCellRendererComponent(JList list, Object value,
704
        int index, boolean isSelected, boolean cellHasFocus)
705
    {
706
      FileView v = getFileView(getFileChooser());
707
      File f = (File) value;
708
      if (f != null)
709
        {
710
          setText(v.getName(f));
711
          setIcon(v.getIcon(f));
712
        }
713
      else
714
        {
715
          setText("");
716
          setIcon(null);
717
        }
718
      setOpaque(true);
719
      if (isSelected)
720
        {
721
          setBackground(list.getSelectionBackground());
722
          setForeground(list.getSelectionForeground());
723
        }
724
      else
725
        {
726
          setBackground(list.getBackground());
727
          setForeground(list.getForeground());
728
        }
729
 
730
      setEnabled(list.isEnabled());
731
      setFont(list.getFont());
732
 
733
      if (cellHasFocus)
734
        setBorder(UIManager.getBorder("List.focusCellHighlightBorder"));
735
      else
736
        setBorder(noFocusBorder);
737
      return this;
738
    }
739
  }
740
 
741
  /**
742
   * A combo box model for the file selection filters.
743
   */
744
  protected class FilterComboBoxModel
745
    extends AbstractListModel
746
    implements ComboBoxModel, PropertyChangeListener
747
  {
748
 
749
    /** Storage for the filters in the model. */
750
    protected FileFilter[] filters;
751
 
752
    /** The index of the selected file filter. */
753
    private Object selected;
754
 
755
    /**
756
     * Creates a new model.
757
     */
758
    protected FilterComboBoxModel()
759
    {
760
      filters = new FileFilter[1];
761
      filters[0] = getAcceptAllFileFilter(getFileChooser());
762
      selected = filters[0];
763
    }
764
 
765
    /**
766
     * Handles property changes.
767
     *
768
     * @param e  the property change event.
769
     */
770
    public void propertyChange(PropertyChangeEvent e)
771
    {
772
      if (e.getPropertyName().equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY))
773
        {
774
          JFileChooser fc = getFileChooser();
775
          FileFilter[] choosableFilters = fc.getChoosableFileFilters();
776
          filters = choosableFilters;
777
          fireContentsChanged(this, 0, filters.length);
778
          selected = e.getNewValue();
779
          fireContentsChanged(this, -1, -1);
780
        }
781
      else if (e.getPropertyName().equals(
782
              JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY))
783
        {
784
          // repopulate list
785
          JFileChooser fc = getFileChooser();
786
          FileFilter[] choosableFilters = fc.getChoosableFileFilters();
787
          filters = choosableFilters;
788
          fireContentsChanged(this, 0, filters.length);
789
        }
790
    }
791
 
792
    /**
793
     * Sets the selected filter.
794
     *
795
     * @param filter  the filter (<code>null</code> ignored).
796
     */
797
    public void setSelectedItem(Object filter)
798
    {
799
      if (filter != null)
800
      {
801
          selected = filter;
802
          fireContentsChanged(this, -1, -1);
803
      }
804
    }
805
 
806
    /**
807
     * Returns the selected file filter.
808
     *
809
     * @return The selected file filter.
810
     */
811
    public Object getSelectedItem()
812
    {
813
      return selected;
814
    }
815
 
816
    /**
817
     * Returns the number of items in the model.
818
     *
819
     * @return The number of items in the model.
820
     */
821
    public int getSize()
822
    {
823
      return filters.length;
824
    }
825
 
826
    /**
827
     * Returns the item at the specified index.
828
     *
829
     * @param index  the item index.
830
     *
831
     * @return The item at the specified index.
832
     */
833
    public Object getElementAt(int index)
834
    {
835
      return filters[index];
836
    }
837
 
838
  }
839
 
840
  /**
841
   * A renderer for the items in the file filter combo box.
842
   */
843
  public class FilterComboBoxRenderer
844
    extends DefaultListCellRenderer
845
  {
846
    /**
847
     * Creates a new renderer.
848
     */
849
    public FilterComboBoxRenderer()
850
    {
851
      // Nothing to do here.
852
    }
853
 
854
    /**
855
     * Returns a component that can be used to paint the given value within
856
     * the list.
857
     *
858
     * @param list  the list.
859
     * @param value  the value (a {@link FileFilter}).
860
     * @param index  the item index.
861
     * @param isSelected  is the item selected?
862
     * @param cellHasFocus  does the list cell have focus?
863
     *
864
     * @return This component as the renderer.
865
     */
866
    public Component getListCellRendererComponent(JList list, Object value,
867
        int index, boolean isSelected, boolean cellHasFocus)
868
    {
869
      super.getListCellRendererComponent(list, value, index, isSelected,
870
                                         cellHasFocus);
871
      FileFilter filter = (FileFilter) value;
872
      setText(filter.getDescription());
873
      return this;
874
    }
875
  }
876
 
877
  /**
878
   * A listener for selection events in the file list.
879
   *
880
   * @see #createListSelectionListener(JFileChooser)
881
   */
882
  class MetalFileChooserSelectionListener
883
    implements ListSelectionListener
884
  {
885
    /**
886
     * Creates a new <code>SelectionListener</code> object.
887
     */
888
    protected MetalFileChooserSelectionListener()
889
    {
890
      // Do nothing here.
891
    }
892
 
893
    /**
894
     * Makes changes to different properties when
895
     * a value has changed in the filechooser's selection.
896
     *
897
     * @param e - the list selection event that occured.
898
     */
899
    public void valueChanged(ListSelectionEvent e)
900
    {
901
      File f = (File) fileList.getSelectedValue();
902
      if (f == null)
903
        return;
904
      JFileChooser filechooser = getFileChooser();
905
      if (! filechooser.isTraversable(f))
906
        filechooser.setSelectedFile(f);
907
      else
908
        filechooser.setSelectedFile(null);
909
    }
910
  }
911
 
912
  /**
913
   * A mouse listener for the {@link JFileChooser}.
914
   * This listener is used for editing filenames.
915
   */
916
  protected class SingleClickListener
917
    extends MouseAdapter
918
  {
919
 
920
    /** Stores instance of the list */
921
    JList list;
922
 
923
    /**
924
     * Stores the current file that is being edited.
925
     * It is null if nothing is currently being edited.
926
     */
927
    File editFile;
928
 
929
    /** The current file chooser. */
930
    JFileChooser fc;
931
 
932
    /** The last file selected. */
933
    Object lastSelected;
934
 
935
    /** The textfield used for editing. */
936
    JTextField editField;
937
 
938
    /**
939
     * Creates a new listener.
940
     *
941
     * @param list  the directory/file list.
942
     */
943
    public SingleClickListener(JList list)
944
    {
945
      this.list = list;
946
      editFile = null;
947
      fc = getFileChooser();
948
      lastSelected = null;
949
      startEditing = false;
950
    }
951
 
952
    /**
953
     * Receives notification of a mouse click event.
954
     *
955
     * @param e  the event.
956
     */
957
    public void mouseClicked(MouseEvent e)
958
    {
959
      if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1)
960
        {
961
          int index = list.locationToIndex(e.getPoint());
962
          File[] sf = fc.getSelectedFiles();
963
          if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
964
              && index >= 0 && !startEditing && list.isSelectedIndex(index))
965
            {
966
              Object tmp = list.getModel().getElementAt(index);
967
              if (lastSelected != null && lastSelected.equals(tmp))
968
                editFile(index);
969
              lastSelected = tmp;
970
            }
971
          else
972
              completeEditing();
973
        }
974
      else
975
        completeEditing();
976
    }
977
 
978
    /**
979
     * Sets up the text editor for the current file.
980
     *
981
     * @param index -
982
     *          the current index of the item in the list to be edited.
983
     */
984
    void editFile(int index)
985
    {
986
      Rectangle bounds = list.getCellBounds(index, index);
987
      list.scrollRectToVisible(bounds);
988
      editFile = (File) list.getModel().getElementAt(index);
989
      if (editFile.canWrite())
990
        {
991
          startEditing = true;
992
          editField = new JTextField(editFile.getName());
993
          editField.addActionListener(new EditingActionListener());
994
 
995
          Icon icon = getFileView(fc).getIcon(editFile);
996
          if (icon != null)
997
            {
998
              int padding = icon.getIconWidth() + 4;
999
              bounds.x += padding;
1000
              bounds.width -= padding;
1001
            }
1002
          editField.setBounds(bounds);
1003
 
1004
          list.add(editField);
1005
 
1006
          editField.requestFocus();
1007
          editField.selectAll();
1008
        }
1009
      else
1010
        completeEditing();
1011
      list.repaint();
1012
    }
1013
 
1014
    /**
1015
     * Completes the editing.
1016
     */
1017
    void completeEditing()
1018
    {
1019
      if (editField != null && editFile != null)
1020
        {
1021
          String text = editField.getText();
1022
          if (text != null && text != "" && !text.equals(fc.getName(editFile)))
1023
            {
1024
              File f = fc.getFileSystemView().
1025
                createFileObject(fc.getCurrentDirectory(), text);
1026
              if ( editFile.renameTo(f) )
1027
                rescanCurrentDirectory(fc);
1028
            }
1029
          list.remove(editField);
1030
        }
1031
      startEditing = false;
1032
      editFile = null;
1033
      lastSelected = null;
1034
      editField = null;
1035
      list.repaint();
1036
    }
1037
 
1038
    /**
1039
     * ActionListener for the editing text field.
1040
     */
1041
    class EditingActionListener implements ActionListener
1042
    {
1043
 
1044
      /**
1045
       * This method is invoked when an action occurs.
1046
       *
1047
       * @param e -
1048
       *          the <code>ActionEvent</code> that occurred
1049
       */
1050
      public void actionPerformed(ActionEvent e)
1051
      {
1052
        if (editField != null)
1053
          completeEditing();
1054
      }
1055
    }
1056
  }
1057
 
1058
  /**
1059
   * A mouse listener for the {@link JFileChooser}.
1060
   * This listener is used for the table
1061
   */
1062
  private class TableClickListener extends MouseAdapter
1063
  {
1064
 
1065
    /** Stores instance of the table */
1066
    JTable table;
1067
 
1068
    /** Stores instance of the file chooser */
1069
    JFileChooser fc;
1070
 
1071
    /** The last selected file. */
1072
    Object lastSelected;
1073
 
1074
    /**
1075
     * Stores the current file that is being edited.
1076
     * It is null if nothing is currently being edited.
1077
     */
1078
    File editFile;
1079
 
1080
    /** The textfield used for editing. */
1081
    JTextField editField;
1082
 
1083
    /**
1084
     * Creates a new listener.
1085
     *
1086
     * @param table the directory/file table
1087
     * @param fc the JFileChooser
1088
     */
1089
    public TableClickListener(JTable table, JFileChooser fc)
1090
    {
1091
      this.table = table;
1092
      this.fc = fc;
1093
      lastSelected = fileList.getSelectedValue();
1094
      setDirectorySelected(false);
1095
      startEditing = false;
1096
      editFile = null;
1097
      editField = null;
1098
    }
1099
 
1100
    /**
1101
     * Receives notification of a mouse click event.
1102
     *
1103
     * @param e the event.
1104
     */
1105
    public void mouseClicked(MouseEvent e)
1106
    {
1107
      int row = table.getSelectedRow();
1108
      Object selVal = fileList.getModel().getElementAt(row);
1109
      if (selVal == null)
1110
        return;
1111
      FileSystemView fsv = fc.getFileSystemView();
1112
      if (e.getClickCount() == 1 &&
1113
          selVal.equals(lastSelected) &&
1114
          e.getButton() == MouseEvent.BUTTON1)
1115
        {
1116
          File[] sf = fc.getSelectedFiles();
1117
          if ((!fc.isMultiSelectionEnabled() || (sf != null && sf.length <= 1))
1118
              && !startEditing)
1119
            {
1120
              editFile = (File) selVal;
1121
              editFile(row);
1122
            }
1123
        }
1124
      else if (e.getClickCount() >= 2 &&
1125
          selVal.equals(lastSelected))
1126
        {
1127
          if (startEditing)
1128
            completeEditing();
1129
          File f = fsv.createFileObject(lastSelected.toString());
1130
          if (fc.isTraversable(f))
1131
            {
1132
              fc.setCurrentDirectory(f);
1133
              fc.rescanCurrentDirectory();
1134
            }
1135
          else
1136
            {
1137
              fc.setSelectedFile(f);
1138
              fc.approveSelection();
1139
              closeDialog();
1140
            }
1141
        }
1142
      else
1143
        {
1144
          if (startEditing)
1145
            completeEditing();
1146
          String path = selVal.toString();
1147
          File f = fsv.createFileObject(path);
1148
          fc.setSelectedFile(f);
1149
          if (fc.isTraversable(f))
1150
            {
1151
              setDirectorySelected(true);
1152
              setDirectory(f);
1153
            }
1154
          else
1155
            {
1156
              setDirectorySelected(false);
1157
              setDirectory(null);
1158
            }
1159
          lastSelected = selVal;
1160
          if (f.isFile())
1161
            setFileName(path.substring(path.lastIndexOf("/") + 1));
1162
          else if (fc.getFileSelectionMode() != JFileChooser.FILES_ONLY)
1163
            setFileName(path);
1164
        }
1165
      fileTable.repaint();
1166
    }
1167
 
1168
    /**
1169
     * Sets up the text editor for the current file.
1170
     *
1171
     * @param row -
1172
     *          the current row of the item in the list to be edited.
1173
     */
1174
    void editFile(int row)
1175
    {
1176
      Rectangle bounds = table.getCellRect(row, 0, true);
1177
      table.scrollRectToVisible(bounds);
1178
      if (editFile.canWrite())
1179
        {
1180
          startEditing = true;
1181
          editField = new JTextField(editFile.getName());
1182
          editField.addActionListener(new EditingActionListener());
1183
 
1184
          // Need to adjust y pos
1185
          bounds.y = row * table.getRowHeight();
1186
          editField.setBounds(bounds);
1187
 
1188
          table.add(editField);
1189
 
1190
          editField.requestFocus();
1191
          editField.selectAll();
1192
        }
1193
      else
1194
        completeEditing();
1195
      table.repaint();
1196
    }
1197
 
1198
    /**
1199
     * Completes the editing.
1200
     */
1201
    void completeEditing()
1202
    {
1203
      if (editField != null && editFile != null)
1204
        {
1205
          String text = editField.getText();
1206
          if (text != null && text != "" && !text.equals(fc.getName(editFile)))
1207
              if (editFile.renameTo(fc.getFileSystemView().createFileObject(
1208
                  fc.getCurrentDirectory(), text)))
1209
                rescanCurrentDirectory(fc);
1210
          table.remove(editField);
1211
        }
1212
      startEditing = false;
1213
      editFile = null;
1214
      editField = null;
1215
      table.repaint();
1216
    }
1217
 
1218
    /**
1219
     * ActionListener for the editing text field.
1220
     */
1221
    class EditingActionListener implements ActionListener
1222
    {
1223
 
1224
      /**
1225
       * This method is invoked when an action occurs.
1226
       *
1227
       * @param e -
1228
       *          the <code>ActionEvent</code> that occurred
1229
       */
1230
      public void actionPerformed(ActionEvent e)
1231
      {
1232
        if (editField != null)
1233
          completeEditing();
1234
      }
1235
    }
1236
 
1237
    /**
1238
     * Closes the dialog.
1239
     */
1240
    public void closeDialog()
1241
    {
1242
      Window owner = SwingUtilities.windowForComponent(fc);
1243
      if (owner instanceof JDialog)
1244
        ((JDialog) owner).dispose();
1245
    }
1246
  }
1247
 
1248
  /** The text for a label describing the directory combo box. */
1249
  private String directoryLabel;
1250
 
1251
  private JComboBox directoryComboBox;
1252
 
1253
  /** The model for the directory combo box. */
1254
  DirectoryComboBoxModel directoryModel;
1255
 
1256
  /** The text for a label describing the file text field. */
1257
  private String fileLabel;
1258
 
1259
  /** The file name text field. */
1260
  private JTextField fileTextField;
1261
 
1262
  /** The text for a label describing the filter combo box. */
1263
  private String filterLabel;
1264
 
1265
  /**
1266
   * The top panel (contains the directory combo box and the control buttons).
1267
   */
1268
  private JPanel topPanel;
1269
 
1270
  /** A panel containing the control buttons ('up', 'home' etc.). */
1271
  private JPanel controls;
1272
 
1273
  /**
1274
   * The panel that contains the filename field and the filter combobox.
1275
   */
1276
  private JPanel bottomPanel;
1277
 
1278
  /**
1279
   * The panel that contains the 'Open' (or 'Save') and 'Cancel' buttons.
1280
   */
1281
  private JPanel buttonPanel;
1282
 
1283
  private JButton approveButton;
1284
 
1285
  /** The file list. */
1286
  JList fileList;
1287
 
1288
  /** The file table. */
1289
  JTable fileTable;
1290
 
1291
  /** The panel containing the file list. */
1292
  JPanel fileListPanel;
1293
 
1294
  /** The panel containing the file table. */
1295
  JPanel fileTablePanel;
1296
 
1297
  /** The filter combo box model. */
1298
  private FilterComboBoxModel filterModel;
1299
 
1300
  /** The action map. */
1301
  private ActionMap actionMap;
1302
 
1303
  /** True if currently in list view. */
1304
  boolean listView;
1305
 
1306
  /** True if we can or have started editing a cell. */
1307
  boolean startEditing;
1308
 
1309
  /** The scrollpane used for the table and list. */
1310
  JScrollPane scrollPane;
1311
 
1312
  /** The text for the label when saving. */
1313
  String save;
1314
 
1315
  /** The text for the label when opening a directory. */
1316
  String look;
1317
 
1318
  /** The label for the file combo box. */
1319
  JLabel dirLabel;
1320
 
1321
  /** Listeners. */
1322
  ListSelectionListener listSelList;
1323
  MouseListener doubleClickList;
1324
  SingleClickListener singleClickList;
1325
  TableClickListener tableClickList;
1326
 
1327
  /**
1328
   * A factory method that returns a UI delegate for the specified
1329
   * component.
1330
   *
1331
   * @param c  the component (which should be a {@link JFileChooser}).
1332
   */
1333
  public static ComponentUI createUI(JComponent c)
1334
  {
1335
    JFileChooser chooser = (JFileChooser) c;
1336
    return new MetalFileChooserUI(chooser);
1337
  }
1338
 
1339
  /**
1340
   * Creates a new instance of this UI delegate.
1341
   *
1342
   * @param filechooser  the file chooser component.
1343
   */
1344
  public MetalFileChooserUI(JFileChooser filechooser)
1345
  {
1346
    super(filechooser);
1347
    bottomPanel = new JPanel(new GridLayout(3, 2));
1348
    buttonPanel = new JPanel();
1349
  }
1350
 
1351
  public void installUI(JComponent c)
1352
  {
1353
    super.installUI(c);
1354
    actionMap = createActionMap();
1355
  }
1356
 
1357
  public void uninstallUI(JComponent c)
1358
  {
1359
    super.uninstallUI(c);
1360
    actionMap = null;
1361
  }
1362
 
1363
  /**
1364
   * Installs the sub-components of the file chooser.
1365
   *
1366
   * @param fc  the file chooser component.
1367
   */
1368
  public void installComponents(JFileChooser fc)
1369
  {
1370
    fc.setLayout(new BorderLayout());
1371
    topPanel = new JPanel(new BorderLayout());
1372
    dirLabel = new JLabel(directoryLabel);
1373
    topPanel.add(dirLabel, BorderLayout.WEST);
1374
    this.controls = new JPanel();
1375
    addControlButtons();
1376
 
1377
    JPanel dirPanel = new JPanel(new VerticalMidLayout());
1378
    directoryModel = createDirectoryComboBoxModel(fc);
1379
    directoryComboBox = new JComboBox(directoryModel);
1380
    directoryComboBox.setRenderer(createDirectoryComboBoxRenderer(fc));
1381
    dirPanel.add(directoryComboBox);
1382
    topPanel.add(dirPanel);
1383
    topPanel.add(controls, BorderLayout.EAST);
1384
    topPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 0, 8));
1385
    fc.add(topPanel, BorderLayout.NORTH);
1386
 
1387
    JPanel list = createList(fc);
1388
    list.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
1389
    fc.add(list, BorderLayout.CENTER);
1390
 
1391
    JPanel bottomPanel = getBottomPanel();
1392
    filterModel = createFilterComboBoxModel();
1393
    JComboBox fileFilterCombo = new JComboBox(filterModel);
1394
    fileFilterCombo.setRenderer(createFilterComboBoxRenderer());
1395
 
1396
    fileTextField = new JTextField();
1397
    JPanel fileNamePanel = new JPanel(new VerticalMidLayout());
1398
    fileNamePanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 5));
1399
    fileNamePanel.add(fileTextField);
1400
    JPanel row1 = new JPanel(new BorderLayout());
1401
    row1.add(new JLabel(this.fileLabel), BorderLayout.WEST);
1402
    row1.add(fileNamePanel);
1403
    bottomPanel.add(row1);
1404
 
1405
    JPanel row2 = new JPanel(new BorderLayout());
1406
    row2.add(new JLabel(this.filterLabel), BorderLayout.WEST);
1407
    row2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
1408
    row2.add(fileFilterCombo);
1409
    bottomPanel.add(row2);
1410
    JPanel buttonPanel = new JPanel(new ButtonLayout());
1411
 
1412
    approveButton = new JButton(getApproveSelectionAction());
1413
    approveButton.setText(getApproveButtonText(fc));
1414
    approveButton.setToolTipText(getApproveButtonToolTipText(fc));
1415
    approveButton.setMnemonic(getApproveButtonMnemonic(fc));
1416
    buttonPanel.add(approveButton);
1417
    buttonPanel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));
1418
 
1419
    JButton cancelButton = new JButton(getCancelSelectionAction());
1420
    cancelButton.setText(cancelButtonText);
1421
    cancelButton.setToolTipText(cancelButtonToolTipText);
1422
    cancelButton.setMnemonic(cancelButtonMnemonic);
1423
    buttonPanel.add(cancelButton);
1424
    bottomPanel.add(buttonPanel, BorderLayout.SOUTH);
1425
    bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 8, 8, 8));
1426
    fc.add(bottomPanel, BorderLayout.SOUTH);
1427
 
1428
    fc.add(getAccessoryPanel(), BorderLayout.EAST);
1429
  }
1430
 
1431
  /**
1432
   * Uninstalls the components added by
1433
   * {@link #installComponents(JFileChooser)}.
1434
   *
1435
   * @param fc  the file chooser.
1436
   */
1437
  public void uninstallComponents(JFileChooser fc)
1438
  {
1439
    fc.remove(bottomPanel);
1440
    bottomPanel = null;
1441
    fc.remove(fileListPanel);
1442
    fc.remove(fileTablePanel);
1443
    fileTablePanel = null;
1444
    fileListPanel = null;
1445
    fc.remove(topPanel);
1446
    topPanel = null;
1447
 
1448
    directoryModel = null;
1449
    fileTextField = null;
1450
    directoryComboBox = null;
1451
  }
1452
 
1453
  /**
1454
   * Returns the panel that contains the 'Open' (or 'Save') and 'Cancel'
1455
   * buttons.
1456
   *
1457
   * @return The panel.
1458
   */
1459
  protected JPanel getButtonPanel()
1460
  {
1461
    return buttonPanel;
1462
  }
1463
 
1464
  /**
1465
   * Creates and returns a new panel that will be used for the controls at
1466
   * the bottom of the file chooser.
1467
   *
1468
   * @return A new panel.
1469
   */
1470
  protected JPanel getBottomPanel()
1471
  {
1472
    if (bottomPanel == null)
1473
      bottomPanel = new JPanel(new GridLayout(3, 2));
1474
    return bottomPanel;
1475
  }
1476
 
1477
  /**
1478
   * Fetches localised strings for use by the labels and buttons on the
1479
   * file chooser.
1480
   *
1481
   * @param fc  the file chooser.
1482
   */
1483
  protected void installStrings(JFileChooser fc)
1484
  {
1485
     super.installStrings(fc);
1486
     look = "Look In: ";
1487
     save = "Save In: ";
1488
     if (fc.getDialogType() == JFileChooser.SAVE_DIALOG)
1489
       directoryLabel = save;
1490
     else
1491
       directoryLabel = look;
1492
 
1493
     fileLabel = "File Name: ";
1494
     filterLabel = "Files of Type: ";
1495
 
1496
     this.cancelButtonMnemonic = 0;
1497
     this.cancelButtonText = "Cancel";
1498
     this.cancelButtonToolTipText = "Abort file chooser dialog";
1499
 
1500
     this.directoryOpenButtonMnemonic = 0;
1501
     this.directoryOpenButtonText = "Open";
1502
     this.directoryOpenButtonToolTipText = "Open selected directory";
1503
 
1504
     this.helpButtonMnemonic = 0;
1505
     this.helpButtonText = "Help";
1506
     this.helpButtonToolTipText = "Filechooser help";
1507
 
1508
     this.openButtonMnemonic = 0;
1509
     this.openButtonText = "Open";
1510
     this.openButtonToolTipText = "Open selected file";
1511
 
1512
     this.saveButtonMnemonic = 0;
1513
     this.saveButtonText = "Save";
1514
     this.saveButtonToolTipText = "Save selected file";
1515
 
1516
     this.updateButtonMnemonic = 0;
1517
     this.updateButtonText = "Update";
1518
     this.updateButtonToolTipText = "Update directory listing";
1519
  }
1520
 
1521
  /**
1522
   * Installs the listeners required.
1523
   *
1524
   * @param fc  the file chooser.
1525
   */
1526
  protected void installListeners(JFileChooser fc)
1527
  {
1528
    directoryComboBox.setAction(new DirectoryComboBoxAction());
1529
    fc.addPropertyChangeListener(filterModel);
1530
    listSelList = createListSelectionListener(fc);
1531
    doubleClickList = this.createDoubleClickListener(fc, fileList);
1532
    singleClickList = new SingleClickListener(fileList);
1533
    fileList.addListSelectionListener(listSelList);
1534
    fileList.addMouseListener(doubleClickList);
1535
    fileList.addMouseListener(singleClickList);
1536
    super.installListeners(fc);
1537
  }
1538
 
1539
  protected void uninstallListeners(JFileChooser fc)
1540
  {
1541
    super.uninstallListeners(fc);
1542
    fc.removePropertyChangeListener(filterModel);
1543
    directoryComboBox.setAction(null);
1544
    fileList.removeListSelectionListener(listSelList);
1545
    fileList.removeMouseListener(doubleClickList);
1546
    fileList.removeMouseListener(singleClickList);
1547
 
1548
    if (fileTable != null)
1549
      fileTable.removeMouseListener(tableClickList);
1550
  }
1551
 
1552
  protected ActionMap getActionMap()
1553
  {
1554
    if (actionMap == null)
1555
      actionMap = createActionMap();
1556
    return actionMap;
1557
  }
1558
 
1559
  /**
1560
   * Creates and returns an action map.
1561
   *
1562
   * @return The action map.
1563
   */
1564
  protected ActionMap createActionMap()
1565
  {
1566
    ActionMap map = new ActionMap();
1567
    map.put("approveSelection", getApproveSelectionAction());
1568
    map.put("cancelSelection", getCancelSelectionAction());
1569
    map.put("Go Up", getChangeToParentDirectoryAction());
1570
    return map;
1571
  }
1572
 
1573
  /**
1574
   * Creates a panel containing a list of files.
1575
   *
1576
   * @param fc  the file chooser.
1577
   *
1578
   * @return A panel.
1579
   */
1580
  protected JPanel createList(JFileChooser fc)
1581
  {
1582
    if (fileList == null)
1583
      {
1584
        fileListPanel = new JPanel(new BorderLayout());
1585
        fileList = new JList(getModel());
1586
        scrollPane = new JScrollPane(fileList);
1587
        fileList.setLayoutOrientation(JList.VERTICAL_WRAP);
1588
        fileList.setCellRenderer(new FileRenderer());
1589
      }
1590
    else
1591
      {
1592
        fileList.setModel(getModel());
1593
        fileListPanel.removeAll();
1594
        scrollPane.getViewport().setView(fileList);
1595
      }
1596
    fileListPanel.add(scrollPane);
1597
    // This size was determined using BeanShell and dumping the JFileChooser
1598
    // component hierarchy. Sun has an internal FilePane class in there, but
1599
    // that probably doesn't matter atm.
1600
    fileListPanel.setPreferredSize(new Dimension(405, 135));
1601
    return fileListPanel;
1602
  }
1603
 
1604
  /**
1605
   * Creates a panel containing a table within a scroll pane.
1606
   *
1607
   * @param fc  the file chooser.
1608
   *
1609
   * @return The details view.
1610
   */
1611
  protected JPanel createDetailsView(JFileChooser fc)
1612
  {
1613
    fileTablePanel = new JPanel(new BorderLayout());
1614
 
1615
    Object[] cols = new Object[] {"Name", "Size", "Modified"};
1616
    Object[][] rows = new Object[fileList.getModel().getSize()][3];
1617
 
1618
    fileTable = new JTable(new DefaultTableModel(rows, cols));
1619
 
1620
    if (fc.isMultiSelectionEnabled())
1621
      fileTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
1622
    else
1623
      fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
1624
 
1625
    fileTable.setShowGrid(false);
1626
    fileTable.setColumnSelectionAllowed(false);
1627
    fileTable.setDefaultRenderer(Object.class, new TableFileRenderer());
1628
 
1629
    tableClickList = new TableClickListener(fileTable, fc);
1630
    fileTable.addMouseListener(tableClickList);
1631
 
1632
    return updateTable();
1633
  }
1634
 
1635
  /**
1636
   * Sets the values in the table, and puts it in the panel.
1637
   *
1638
   * @return the panel containing the table.
1639
   */
1640
  JPanel updateTable()
1641
  {
1642
    DefaultTableModel mod = (DefaultTableModel) fileTable.getModel();
1643
    ListModel lm = fileList.getModel();
1644
    DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.SHORT,
1645
                                                   DateFormat.SHORT);
1646
    File curr = null;
1647
    int size = lm.getSize();
1648
    int rc = mod.getRowCount();
1649
 
1650
    // If there are not enough rows
1651
    for (int x = rc; x < size; x++)
1652
      mod.addRow(new Object[3]);
1653
 
1654
    for (int i = 0; i < size; i++)
1655
      {
1656
        curr = (File) lm.getElementAt(i);
1657
        fileTable.setValueAt(curr.getName(), i, 0);
1658
        fileTable.setValueAt(formatSize(curr.length()), i, 1);
1659
        fileTable.setValueAt(dt.format(new Date(curr.lastModified())), i, 2);
1660
      }
1661
 
1662
    // If there are too many rows
1663
    while (rc > size)
1664
      mod.removeRow(--rc);
1665
 
1666
    scrollPane.getViewport().setView(fileTable);
1667
    scrollPane.setColumnHeaderView(fileTable.getTableHeader());
1668
 
1669
    fileTablePanel.removeAll();
1670
    fileTablePanel.add(scrollPane);
1671
 
1672
    return fileTablePanel;
1673
  }
1674
 
1675
  /**
1676
   * Formats bytes into the appropriate size.
1677
   *
1678
   * @param bytes the number of bytes to convert
1679
   * @return a string representation of the size
1680
   */
1681
  private String formatSize(long bytes)
1682
  {
1683
    NumberFormat nf = NumberFormat.getNumberInstance();
1684
    long mb = (long) Math.pow(2, 20);
1685
    long kb = (long) Math.pow(2, 10);
1686
    long gb = (long) Math.pow(2, 30);
1687
    double size = 0;
1688
    String id = "";
1689
 
1690
    if ((bytes / gb) >= 1)
1691
      {
1692
        size = (double) bytes / (double) gb;
1693
        id = "GB";
1694
      }
1695
    else if ((bytes / mb) >= 1)
1696
      {
1697
        size = (double) bytes / (double) mb;
1698
        id = "MB";
1699
      }
1700
    else if ((bytes / kb) >= 1)
1701
      {
1702
        size = (double) bytes / (double) kb;
1703
        id = "KB";
1704
      }
1705
    else
1706
      {
1707
        size = bytes;
1708
        id = "Bytes";
1709
      }
1710
 
1711
    return nf.format(size) + " " + id;
1712
  }
1713
  /**
1714
   * Creates a listener that monitors selections in the directory/file list
1715
   * and keeps the {@link JFileChooser} component up to date.
1716
   *
1717
   * @param fc  the file chooser.
1718
   *
1719
   * @return The listener.
1720
   *
1721
   * @see #installListeners(JFileChooser)
1722
   */
1723
  public ListSelectionListener createListSelectionListener(JFileChooser fc)
1724
  {
1725
    return new MetalFileChooserSelectionListener();
1726
  }
1727
 
1728
  /**
1729
   * Returns the preferred size for the file chooser component.
1730
   *
1731
   * @return The preferred size.
1732
   */
1733
  public Dimension getPreferredSize(JComponent c)
1734
  {
1735
    Dimension tp = topPanel.getPreferredSize();
1736
    Dimension bp = bottomPanel.getPreferredSize();
1737
    Dimension fl = fileListPanel.getPreferredSize();
1738
    return new Dimension(fl.width, tp.height + bp.height + fl.height);
1739
  }
1740
 
1741
  /**
1742
   * Returns the minimum size for the file chooser component.
1743
   *
1744
   * @return The minimum size.
1745
   */
1746
  public Dimension getMinimumSize(JComponent c)
1747
  {
1748
    Dimension tp = topPanel.getMinimumSize();
1749
    Dimension bp = bottomPanel.getMinimumSize();
1750
    Dimension fl = fileListPanel.getMinimumSize();
1751
    return new Dimension(fl.width, tp.height + bp.height + fl.height);
1752
  }
1753
 
1754
  /**
1755
   * Returns the maximum size for the file chooser component.
1756
   *
1757
   * @return The maximum size.
1758
   */
1759
  public Dimension getMaximumSize(JComponent c)
1760
  {
1761
    return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1762
  }
1763
 
1764
  /**
1765
   * Creates a property change listener that monitors the {@link JFileChooser}
1766
   * for property change events and updates the component display accordingly.
1767
   *
1768
   * @param fc  the file chooser.
1769
   *
1770
   * @return The property change listener.
1771
   *
1772
   * @see #installListeners(JFileChooser)
1773
   */
1774
  public PropertyChangeListener createPropertyChangeListener(JFileChooser fc)
1775
  {
1776
    return new MetalFileChooserPropertyChangeListener();
1777
  }
1778
 
1779
  /**
1780
   * Creates and returns a new instance of {@link DirectoryComboBoxModel}.
1781
   *
1782
   * @return A new instance of {@link DirectoryComboBoxModel}.
1783
   */
1784
  protected MetalFileChooserUI.DirectoryComboBoxModel
1785
      createDirectoryComboBoxModel(JFileChooser fc)
1786
  {
1787
    return new DirectoryComboBoxModel();
1788
  }
1789
 
1790
  /**
1791
   * Creates a new instance of the renderer used in the directory
1792
   * combo box.
1793
   *
1794
   * @param fc  the file chooser.
1795
   *
1796
   * @return The renderer.
1797
   */
1798
  protected DirectoryComboBoxRenderer createDirectoryComboBoxRenderer(
1799
          JFileChooser fc)
1800
  {
1801
    return new DirectoryComboBoxRenderer(fc);
1802
  }
1803
 
1804
  /**
1805
   * Creates and returns a new instance of {@link FilterComboBoxModel}.
1806
   *
1807
   * @return A new instance of {@link FilterComboBoxModel}.
1808
   */
1809
  protected FilterComboBoxModel createFilterComboBoxModel()
1810
  {
1811
    return new FilterComboBoxModel();
1812
  }
1813
 
1814
  /**
1815
   * Creates and returns a new instance of {@link FilterComboBoxRenderer}.
1816
   *
1817
   * @return A new instance of {@link FilterComboBoxRenderer}.
1818
   */
1819
  protected MetalFileChooserUI.FilterComboBoxRenderer
1820
      createFilterComboBoxRenderer()
1821
  {
1822
    return new FilterComboBoxRenderer();
1823
  }
1824
 
1825
  /**
1826
   * Adds the control buttons ('up', 'home' etc.) to the panel.
1827
   */
1828
  protected void addControlButtons()
1829
  {
1830
    JButton upButton = new JButton(getChangeToParentDirectoryAction());
1831
    upButton.setText(null);
1832
    upButton.setIcon(this.upFolderIcon);
1833
    upButton.setMargin(new Insets(0, 0, 0, 0));
1834
    controls.add(upButton);
1835
 
1836
    JButton homeButton = new JButton(getGoHomeAction());
1837
    homeButton.setText(null);
1838
    homeButton.setIcon(this.homeFolderIcon);
1839
    homeButton.setMargin(new Insets(0, 0, 0, 0));
1840
    controls.add(homeButton);
1841
 
1842
    JButton newFolderButton = new JButton(getNewFolderAction());
1843
    newFolderButton.setText(null);
1844
    newFolderButton.setIcon(this.newFolderIcon);
1845
    newFolderButton.setMargin(new Insets(0, 0, 0, 0));
1846
    controls.add(newFolderButton);
1847
 
1848
    JToggleButton listButton = new JToggleButton(this.listViewIcon);
1849
    listButton.setMargin(new Insets(0, 0, 0, 0));
1850
    listButton.addActionListener(new ListViewActionListener());
1851
    listButton.setSelected(true);
1852
    listView = true;
1853
    controls.add(listButton);
1854
 
1855
    JToggleButton detailButton = new JToggleButton(this.detailsViewIcon);
1856
    detailButton.setMargin(new Insets(0, 0, 0, 0));
1857
    detailButton.addActionListener(new DetailViewActionListener());
1858
    detailButton.setSelected(false);
1859
    controls.add(detailButton);
1860
 
1861
    ButtonGroup buttonGroup = new ButtonGroup();
1862
    buttonGroup.add(listButton);
1863
    buttonGroup.add(detailButton);
1864
  }
1865
 
1866
  /**
1867
   * Removes all the buttons from the control panel.
1868
   */
1869
  protected void removeControlButtons()
1870
  {
1871
    controls.removeAll();
1872
    controls.revalidate();
1873
    controls.repaint();
1874
  }
1875
 
1876
  /**
1877
   * Updates the current directory.
1878
   *
1879
   * @param fc  the file chooser to update.
1880
   */
1881
  public void rescanCurrentDirectory(JFileChooser fc)
1882
  {
1883
    directoryModel.setSelectedItem(fc.getCurrentDirectory());
1884
    getModel().validateFileCache();
1885
    if (!listView)
1886
        updateTable();
1887
    else
1888
      createList(fc);
1889
  }
1890
 
1891
  /**
1892
   * Returns the file name in the text field.
1893
   *
1894
   * @return The file name.
1895
   */
1896
  public String getFileName()
1897
  {
1898
    String result = null;
1899
    if (fileTextField != null)
1900
      result = fileTextField.getText();
1901
    return result;
1902
  }
1903
 
1904
  /**
1905
   * Sets the file name in the text field.
1906
   *
1907
   * @param filename  the file name.
1908
   */
1909
  public void setFileName(String filename)
1910
  {
1911
    fileTextField.setText(filename);
1912
  }
1913
 
1914
  /**
1915
   * DOCUMENT ME!!
1916
   *
1917
   * @param e - DOCUMENT ME!
1918
   */
1919
  public void valueChanged(ListSelectionEvent e)
1920
  {
1921
    // FIXME: Not sure what we should be doing here, if anything.
1922
  }
1923
 
1924
  /**
1925
   * Returns the approve button.
1926
   *
1927
   * @return The approve button.
1928
   */
1929
  protected JButton getApproveButton(JFileChooser fc)
1930
  {
1931
    return approveButton;
1932
  }
1933
 
1934
  /**
1935
   * A layout manager that is used to arrange the subcomponents of the
1936
   * {@link JFileChooser}.
1937
   */
1938
  class VerticalMidLayout implements LayoutManager
1939
  {
1940
    /**
1941
     * Performs the layout.
1942
     *
1943
     * @param parent  the container.
1944
     */
1945
    public void layoutContainer(Container parent)
1946
    {
1947
      int count = parent.getComponentCount();
1948
      if (count > 0)
1949
        {
1950
          Insets insets = parent.getInsets();
1951
          Component c = parent.getComponent(0);
1952
          Dimension prefSize = c.getPreferredSize();
1953
          int h = parent.getHeight() - insets.top - insets.bottom;
1954
          int adj = Math.max(0, (h - prefSize.height) / 2);
1955
          c.setBounds(insets.left, insets.top + adj, parent.getWidth()
1956
              - insets.left - insets.right,
1957
              (int) Math.min(prefSize.getHeight(), h));
1958
        }
1959
    }
1960
 
1961
    /**
1962
     * Returns the minimum layout size.
1963
     *
1964
     * @param parent  the container.
1965
     *
1966
     * @return The minimum layout size.
1967
     */
1968
    public Dimension minimumLayoutSize(Container parent)
1969
    {
1970
      return preferredLayoutSize(parent);
1971
    }
1972
 
1973
    /**
1974
     * Returns the preferred layout size.
1975
     *
1976
     * @param parent  the container.
1977
     *
1978
     * @return The preferred layout size.
1979
     */
1980
    public Dimension preferredLayoutSize(Container parent)
1981
    {
1982
      if (parent.getComponentCount() > 0)
1983
        {
1984
          return parent.getComponent(0).getPreferredSize();
1985
        }
1986
      else return null;
1987
    }
1988
 
1989
    /**
1990
     * This layout manager does not need to track components, so this
1991
     * method does nothing.
1992
     *
1993
     * @param name  the name the component is associated with.
1994
     * @param component  the component.
1995
     */
1996
    public void addLayoutComponent(String name, Component component)
1997
    {
1998
      // do nothing
1999
    }
2000
 
2001
    /**
2002
     * This layout manager does not need to track components, so this
2003
     * method does nothing.
2004
     *
2005
     * @param component  the component.
2006
     */
2007
    public void removeLayoutComponent(Component component)
2008
    {
2009
      // do nothing
2010
    }
2011
  }
2012
 
2013
  /**
2014
   * A layout manager that is used to arrange buttons for the
2015
   * {@link JFileChooser}.
2016
   */
2017
  class ButtonLayout implements LayoutManager
2018
  {
2019
    static final int GAP = 4;
2020
 
2021
    /**
2022
     * Performs the layout.
2023
     *
2024
     * @param parent  the container.
2025
     */
2026
    public void layoutContainer(Container parent)
2027
    {
2028
      int count = parent.getComponentCount();
2029
      if (count > 0)
2030
        {
2031
          // first find the widest button
2032
          int maxW = 0;
2033
          for (int i = 0; i < count; i++)
2034
            {
2035
              Component c = parent.getComponent(i);
2036
              Dimension prefSize = c.getPreferredSize();
2037
              maxW = Math.max(prefSize.width, maxW);
2038
            }
2039
 
2040
          // then position the buttons
2041
          Insets insets = parent.getInsets();
2042
          int availableH = parent.getHeight() - insets.top - insets.bottom;
2043
          int currentX = parent.getWidth() - insets.right;
2044
          for (int i = count - 1; i >= 0; i--)
2045
            {
2046
              Component c = parent.getComponent(i);
2047
              Dimension prefSize = c.getPreferredSize();
2048
              int adj = Math.max(0, (availableH - prefSize.height) / 2);
2049
              currentX = currentX - prefSize.width;
2050
              c.setBounds(currentX, insets.top + adj, prefSize.width,
2051
                  (int) Math.min(prefSize.getHeight(), availableH));
2052
              currentX = currentX - GAP;
2053
            }
2054
        }
2055
    }
2056
 
2057
    /**
2058
     * Returns the minimum layout size.
2059
     *
2060
     * @param parent  the container.
2061
     *
2062
     * @return The minimum layout size.
2063
     */
2064
    public Dimension minimumLayoutSize(Container parent)
2065
    {
2066
      return preferredLayoutSize(parent);
2067
    }
2068
 
2069
    /**
2070
     * Returns the preferred layout size.
2071
     *
2072
     * @param parent  the container.
2073
     *
2074
     * @return The preferred layout size.
2075
     */
2076
    public Dimension preferredLayoutSize(Container parent)
2077
    {
2078
      Insets insets = parent.getInsets();
2079
      int maxW = 0;
2080
      int maxH = 0;
2081
      int count = parent.getComponentCount();
2082
      if (count > 0)
2083
        {
2084
          for (int i = 0; i < count; i++)
2085
            {
2086
              Component c = parent.getComponent(i);
2087
              Dimension d = c.getPreferredSize();
2088
              maxW = Math.max(d.width, maxW);
2089
              maxH = Math.max(d.height, maxH);
2090
            }
2091
        }
2092
      return new Dimension(maxW * count + GAP * (count - 1) + insets.left
2093
              + insets.right, maxH + insets.top + insets.bottom);
2094
    }
2095
 
2096
    /**
2097
     * This layout manager does not need to track components, so this
2098
     * method does nothing.
2099
     *
2100
     * @param name  the name the component is associated with.
2101
     * @param component  the component.
2102
     */
2103
    public void addLayoutComponent(String name, Component component)
2104
    {
2105
      // do nothing
2106
    }
2107
 
2108
    /**
2109
     * This layout manager does not need to track components, so this
2110
     * method does nothing.
2111
     *
2112
     * @param component  the component.
2113
     */
2114
    public void removeLayoutComponent(Component component)
2115
    {
2116
      // do nothing
2117
    }
2118
  }
2119
 
2120
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.