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. */ |
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. |
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 |
/** |
/** |
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()); |
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. |
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 |
/** |
/** |
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( |
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 |
/** |
/** |
529 |
*/ |
*/ |
530 |
public Object getSelectedItem() |
public Object getSelectedItem() |
531 |
{ |
{ |
532 |
if (selectedIndex >= 0) |
return selected; |
|
return filters[selectedIndex]; |
|
|
return null; |
|
533 |
} |
} |
534 |
|
|
535 |
/** |
/** |
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. |
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. |
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}. |
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}. |
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 |
} |
} |