You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1403 lines
52 KiB
1403 lines
52 KiB
/*
|
|
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
package com.sun.java.swing.plaf.gtk;
|
|
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.beans.*;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.text.MessageFormat;
|
|
import java.util.*;
|
|
|
|
import javax.swing.*;
|
|
import javax.swing.border.*;
|
|
import javax.swing.filechooser.*;
|
|
import javax.swing.event.*;
|
|
import javax.swing.plaf.*;
|
|
import javax.swing.plaf.basic.BasicDirectoryModel;
|
|
import javax.swing.table.*;
|
|
import javax.accessibility.*;
|
|
|
|
import sun.swing.SwingUtilities2;
|
|
|
|
import sun.swing.plaf.synth.*;
|
|
import sun.swing.FilePane;
|
|
import sun.awt.shell.ShellFolder;
|
|
|
|
/**
|
|
* GTK FileChooserUI.
|
|
*
|
|
* @author Leif Samuelsson
|
|
* @author Jeff Dinkins
|
|
*/
|
|
class GTKFileChooserUI extends SynthFileChooserUI {
|
|
|
|
// The accessoryPanel is a container to place the JFileChooser accessory component
|
|
private JPanel accessoryPanel = null;
|
|
|
|
private String newFolderButtonText = null;
|
|
private String newFolderErrorSeparator = null;
|
|
private String newFolderErrorText = null;
|
|
private String newFolderDialogText = null;
|
|
private String newFolderNoDirectoryErrorTitleText = null;
|
|
private String newFolderNoDirectoryErrorText = null;
|
|
|
|
private String deleteFileButtonText = null;
|
|
private String renameFileButtonText = null;
|
|
|
|
private String newFolderButtonToolTipText = null;
|
|
private String deleteFileButtonToolTipText = null;
|
|
private String renameFileButtonToolTipText = null;
|
|
|
|
private int newFolderButtonMnemonic = 0;
|
|
private int deleteFileButtonMnemonic = 0;
|
|
private int renameFileButtonMnemonic = 0;
|
|
private int foldersLabelMnemonic = 0;
|
|
private int filesLabelMnemonic = 0;
|
|
|
|
private String renameFileDialogText = null;
|
|
private String renameFileErrorTitle = null;
|
|
private String renameFileErrorText = null;
|
|
|
|
private JComboBox filterComboBox;
|
|
private FilterComboBoxModel filterComboBoxModel;
|
|
|
|
// From Motif
|
|
|
|
private JPanel rightPanel;
|
|
private JList directoryList;
|
|
private JList fileList;
|
|
|
|
private JLabel pathField;
|
|
private JTextField fileNameTextField;
|
|
|
|
private static final Dimension hstrut3 = new Dimension(3, 1);
|
|
private static final Dimension vstrut10 = new Dimension(1, 10);
|
|
|
|
private static Dimension prefListSize = new Dimension(75, 150);
|
|
|
|
private static Dimension PREF_SIZE = new Dimension(435, 360);
|
|
private static final int MIN_WIDTH = 200;
|
|
private static final int MIN_HEIGHT = 300;
|
|
|
|
private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
|
|
|
|
private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
|
|
|
|
private static final Insets buttonMargin = new Insets(3, 3, 3, 3);
|
|
|
|
private String filesLabelText = null;
|
|
private String foldersLabelText = null;
|
|
private String pathLabelText = null;
|
|
private String filterLabelText = null;
|
|
|
|
private int pathLabelMnemonic = 0;
|
|
private int filterLabelMnemonic = 0;
|
|
|
|
private JComboBox directoryComboBox;
|
|
private DirectoryComboBoxModel directoryComboBoxModel;
|
|
private Action directoryComboBoxAction = new DirectoryComboBoxAction();
|
|
private JPanel bottomButtonPanel;
|
|
private GTKDirectoryModel model = null;
|
|
private Action newFolderAction;
|
|
private boolean readOnly;
|
|
private boolean showDirectoryIcons;
|
|
private boolean showFileIcons;
|
|
private GTKFileView fileView = new GTKFileView();
|
|
private PropertyChangeListener gtkFCPropertyChangeListener;
|
|
private Action approveSelectionAction = new GTKApproveSelectionAction();
|
|
private GTKDirectoryListModel directoryListModel;
|
|
|
|
public GTKFileChooserUI(JFileChooser filechooser) {
|
|
super(filechooser);
|
|
}
|
|
|
|
protected ActionMap createActionMap() {
|
|
ActionMap map = new ActionMapUIResource();
|
|
map.put("approveSelection", getApproveSelectionAction());
|
|
map.put("cancelSelection", getCancelSelectionAction());
|
|
map.put("Go Up", getChangeToParentDirectoryAction());
|
|
map.put("fileNameCompletion", getFileNameCompletionAction());
|
|
return map;
|
|
}
|
|
|
|
public String getFileName() {
|
|
JFileChooser fc = getFileChooser();
|
|
String typedInName = fileNameTextField != null ?
|
|
fileNameTextField.getText() : null;
|
|
|
|
if (!fc.isMultiSelectionEnabled()) {
|
|
return typedInName;
|
|
}
|
|
|
|
int mode = fc.getFileSelectionMode();
|
|
JList list = mode == JFileChooser.DIRECTORIES_ONLY ?
|
|
directoryList : fileList;
|
|
Object[] files = list.getSelectedValues();
|
|
int len = files.length;
|
|
Vector<String> result = new Vector<String>(len + 1);
|
|
|
|
// we return all selected file names
|
|
for (int i = 0; i < len; i++) {
|
|
File file = (File)files[i];
|
|
result.add(file.getName());
|
|
}
|
|
// plus the file name typed into the text field, if not already there
|
|
if (typedInName != null && !result.contains(typedInName)) {
|
|
result.add(typedInName);
|
|
}
|
|
|
|
StringBuffer buf = new StringBuffer();
|
|
len = result.size();
|
|
|
|
// construct the resulting string
|
|
for (int i=0; i<len; i++) {
|
|
if (i > 0) {
|
|
buf.append(" ");
|
|
}
|
|
if (len > 1) {
|
|
buf.append("\"");
|
|
}
|
|
buf.append(result.get(i));
|
|
if (len > 1) {
|
|
buf.append("\"");
|
|
}
|
|
}
|
|
return buf.toString();
|
|
}
|
|
|
|
public void setFileName(String fileName) {
|
|
if (fileNameTextField != null) {
|
|
fileNameTextField.setText(fileName);
|
|
}
|
|
}
|
|
|
|
// public String getDirectoryName() {
|
|
// return pathField.getText();
|
|
// }
|
|
|
|
public void setDirectoryName(String dirname) {
|
|
pathField.setText(dirname);
|
|
}
|
|
|
|
public void ensureFileIsVisible(JFileChooser fc, File f) {
|
|
// PENDING
|
|
}
|
|
|
|
public void rescanCurrentDirectory(JFileChooser fc) {
|
|
getModel().validateFileCache();
|
|
}
|
|
|
|
public JPanel getAccessoryPanel() {
|
|
return accessoryPanel;
|
|
}
|
|
|
|
// ***********************
|
|
// * FileView operations *
|
|
// ***********************
|
|
|
|
public FileView getFileView(JFileChooser fc) {
|
|
return fileView;
|
|
}
|
|
|
|
private class GTKFileView extends BasicFileView {
|
|
public GTKFileView() {
|
|
iconCache = null;
|
|
}
|
|
|
|
public void clearIconCache() {
|
|
}
|
|
|
|
public Icon getCachedIcon(File f) {
|
|
return null;
|
|
}
|
|
|
|
public void cacheIcon(File f, Icon i) {
|
|
}
|
|
|
|
public Icon getIcon(File f) {
|
|
return (f != null && f.isDirectory()) ? directoryIcon : fileIcon;
|
|
}
|
|
}
|
|
|
|
|
|
private void updateDefaultButton() {
|
|
JFileChooser filechooser = getFileChooser();
|
|
JRootPane root = SwingUtilities.getRootPane(filechooser);
|
|
if (root == null) {
|
|
return;
|
|
}
|
|
|
|
if (filechooser.getControlButtonsAreShown()) {
|
|
if (root.getDefaultButton() == null) {
|
|
root.setDefaultButton(getApproveButton(filechooser));
|
|
getCancelButton(filechooser).setDefaultCapable(false);
|
|
}
|
|
} else {
|
|
if (root.getDefaultButton() == getApproveButton(filechooser)) {
|
|
root.setDefaultButton(null);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void doSelectedFileChanged(PropertyChangeEvent e) {
|
|
super.doSelectedFileChanged(e);
|
|
File f = (File) e.getNewValue();
|
|
if (f != null) {
|
|
setFileName(getFileChooser().getName(f));
|
|
}
|
|
}
|
|
|
|
protected void doDirectoryChanged(PropertyChangeEvent e) {
|
|
directoryList.clearSelection();
|
|
ListSelectionModel sm = directoryList.getSelectionModel();
|
|
if (sm instanceof DefaultListSelectionModel) {
|
|
((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
|
|
sm.setAnchorSelectionIndex(0);
|
|
}
|
|
fileList.clearSelection();
|
|
sm = fileList.getSelectionModel();
|
|
if (sm instanceof DefaultListSelectionModel) {
|
|
((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
|
|
sm.setAnchorSelectionIndex(0);
|
|
}
|
|
|
|
File currentDirectory = getFileChooser().getCurrentDirectory();
|
|
if (currentDirectory != null) {
|
|
try {
|
|
setDirectoryName(ShellFolder.getNormalizedFile((File)e.getNewValue()).getPath());
|
|
} catch (IOException ioe) {
|
|
setDirectoryName(((File)e.getNewValue()).getAbsolutePath());
|
|
}
|
|
if ((getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) && !getFileChooser().isMultiSelectionEnabled()) {
|
|
setFileName(pathField.getText());
|
|
}
|
|
directoryComboBoxModel.addItem(currentDirectory);
|
|
directoryListModel.directoryChanged();
|
|
}
|
|
super.doDirectoryChanged(e);
|
|
}
|
|
|
|
protected void doAccessoryChanged(PropertyChangeEvent e) {
|
|
if (getAccessoryPanel() != null) {
|
|
if (e.getOldValue() != null) {
|
|
getAccessoryPanel().remove((JComponent)e.getOldValue());
|
|
}
|
|
JComponent accessory = (JComponent)e.getNewValue();
|
|
if (accessory != null) {
|
|
getAccessoryPanel().add(accessory, BorderLayout.CENTER);
|
|
getAccessoryPanel().setPreferredSize(accessory.getPreferredSize());
|
|
getAccessoryPanel().setMaximumSize(MAX_SIZE);
|
|
} else {
|
|
getAccessoryPanel().setPreferredSize(ZERO_ACC_SIZE);
|
|
getAccessoryPanel().setMaximumSize(ZERO_ACC_SIZE);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void doFileSelectionModeChanged(PropertyChangeEvent e) {
|
|
directoryList.clearSelection();
|
|
rightPanel.setVisible(((Integer)e.getNewValue()).intValue() != JFileChooser.DIRECTORIES_ONLY);
|
|
|
|
super.doFileSelectionModeChanged(e);
|
|
}
|
|
|
|
protected void doMultiSelectionChanged(PropertyChangeEvent e) {
|
|
if (getFileChooser().isMultiSelectionEnabled()) {
|
|
fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
|
} else {
|
|
fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
fileList.clearSelection();
|
|
}
|
|
|
|
super.doMultiSelectionChanged(e);
|
|
}
|
|
|
|
protected void doControlButtonsChanged(PropertyChangeEvent e) {
|
|
super.doControlButtonsChanged(e);
|
|
|
|
JFileChooser filechooser = getFileChooser();
|
|
if (filechooser.getControlButtonsAreShown()) {
|
|
filechooser.add(bottomButtonPanel, BorderLayout.SOUTH);
|
|
} else {
|
|
filechooser.remove(bottomButtonPanel);
|
|
}
|
|
updateDefaultButton();
|
|
}
|
|
|
|
protected void doAncestorChanged(PropertyChangeEvent e) {
|
|
if (e.getOldValue() == null && e.getNewValue() != null) {
|
|
// Ancestor was added, set initial focus
|
|
fileNameTextField.selectAll();
|
|
fileNameTextField.requestFocus();
|
|
updateDefaultButton();
|
|
}
|
|
|
|
super.doAncestorChanged(e);
|
|
}
|
|
|
|
|
|
|
|
// ********************************************
|
|
// ************ Create Listeners **************
|
|
// ********************************************
|
|
|
|
public ListSelectionListener createListSelectionListener(JFileChooser fc) {
|
|
return new SelectionListener();
|
|
}
|
|
|
|
class DoubleClickListener extends MouseAdapter {
|
|
JList list;
|
|
public DoubleClickListener(JList list) {
|
|
this.list = list;
|
|
}
|
|
|
|
public void mouseClicked(MouseEvent e) {
|
|
if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
|
|
int index = list.locationToIndex(e.getPoint());
|
|
if (index >= 0) {
|
|
File f = (File) list.getModel().getElementAt(index);
|
|
try {
|
|
// Strip trailing ".."
|
|
f = ShellFolder.getNormalizedFile(f);
|
|
} catch (IOException ex) {
|
|
// That's ok, we'll use f as is
|
|
}
|
|
if (getFileChooser().isTraversable(f)) {
|
|
list.clearSelection();
|
|
if (getFileChooser().getCurrentDirectory().equals(f)){
|
|
rescanCurrentDirectory(getFileChooser());
|
|
} else {
|
|
getFileChooser().setCurrentDirectory(f);
|
|
}
|
|
} else {
|
|
getFileChooser().approveSelection();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void mouseEntered(MouseEvent evt) {
|
|
if (list != null) {
|
|
TransferHandler th1 = getFileChooser().getTransferHandler();
|
|
TransferHandler th2 = list.getTransferHandler();
|
|
if (th1 != th2) {
|
|
list.setTransferHandler(th1);
|
|
}
|
|
if (getFileChooser().getDragEnabled() != list.getDragEnabled()) {
|
|
list.setDragEnabled(getFileChooser().getDragEnabled());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected MouseListener createDoubleClickListener(JFileChooser fc, JList list) {
|
|
return new DoubleClickListener(list);
|
|
}
|
|
|
|
|
|
|
|
protected class SelectionListener implements ListSelectionListener {
|
|
public void valueChanged(ListSelectionEvent e) {
|
|
if (!e.getValueIsAdjusting()) {
|
|
JFileChooser chooser = getFileChooser();
|
|
JList list = (JList) e.getSource();
|
|
|
|
if (chooser.isMultiSelectionEnabled()) {
|
|
File[] files = null;
|
|
Object[] objects = list.getSelectedValues();
|
|
if (objects != null) {
|
|
if (objects.length == 1
|
|
&& ((File)objects[0]).isDirectory()
|
|
&& chooser.isTraversable(((File)objects[0]))
|
|
&& (chooser.getFileSelectionMode() != chooser.DIRECTORIES_ONLY
|
|
|| !chooser.getFileSystemView().isFileSystem(((File)objects[0])))) {
|
|
setDirectorySelected(true);
|
|
setDirectory(((File)objects[0]));
|
|
} else {
|
|
ArrayList<File> fList = new ArrayList<File>(objects.length);
|
|
for (Object object : objects) {
|
|
File f = (File) object;
|
|
if ((chooser.isFileSelectionEnabled() && f.isFile())
|
|
|| (chooser.isDirectorySelectionEnabled() && f.isDirectory())) {
|
|
fList.add(f);
|
|
}
|
|
}
|
|
if (fList.size() > 0) {
|
|
files = fList.toArray(new File[fList.size()]);
|
|
}
|
|
setDirectorySelected(false);
|
|
}
|
|
}
|
|
chooser.setSelectedFiles(files);
|
|
} else {
|
|
File file = (File)list.getSelectedValue();
|
|
if (file != null
|
|
&& file.isDirectory()
|
|
&& chooser.isTraversable(file)
|
|
&& (chooser.getFileSelectionMode() == chooser.FILES_ONLY
|
|
|| !chooser.getFileSystemView().isFileSystem(file))) {
|
|
|
|
setDirectorySelected(true);
|
|
setDirectory(file);
|
|
} else {
|
|
setDirectorySelected(false);
|
|
if (file != null) {
|
|
chooser.setSelectedFile(file);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// ComponentUI Interface Implementation methods
|
|
//
|
|
public static ComponentUI createUI(JComponent c) {
|
|
return new GTKFileChooserUI((JFileChooser)c);
|
|
}
|
|
|
|
public void installUI(JComponent c) {
|
|
accessoryPanel = new JPanel(new BorderLayout(10, 10));
|
|
accessoryPanel.setName("GTKFileChooser.accessoryPanel");
|
|
|
|
super.installUI(c);
|
|
}
|
|
|
|
public void uninstallUI(JComponent c) {
|
|
c.removePropertyChangeListener(filterComboBoxModel);
|
|
super.uninstallUI(c);
|
|
|
|
if (accessoryPanel != null) {
|
|
accessoryPanel.removeAll();
|
|
}
|
|
accessoryPanel = null;
|
|
getFileChooser().removeAll();
|
|
}
|
|
|
|
public void installComponents(JFileChooser fc) {
|
|
super.installComponents(fc);
|
|
|
|
boolean leftToRight = fc.getComponentOrientation().isLeftToRight();
|
|
|
|
fc.setLayout(new BorderLayout());
|
|
fc.setAlignmentX(JComponent.CENTER_ALIGNMENT);
|
|
|
|
// Top row of buttons
|
|
JPanel topButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
|
|
topButtonPanel.setBorder(new EmptyBorder(10, 10, 0, 10));
|
|
topButtonPanel.setName("GTKFileChooser.topButtonPanel");
|
|
|
|
if (!UIManager.getBoolean("FileChooser.readOnly")) {
|
|
JButton newFolderButton = new JButton(getNewFolderAction());
|
|
newFolderButton.setName("GTKFileChooser.newFolderButton");
|
|
newFolderButton.setMnemonic(newFolderButtonMnemonic);
|
|
newFolderButton.setToolTipText(newFolderButtonToolTipText);
|
|
newFolderButton.setText(newFolderButtonText);
|
|
topButtonPanel.add(newFolderButton);
|
|
}
|
|
JButton deleteFileButton = new JButton(deleteFileButtonText);
|
|
deleteFileButton.setName("GTKFileChooser.deleteFileButton");
|
|
deleteFileButton.setMnemonic(deleteFileButtonMnemonic);
|
|
deleteFileButton.setToolTipText(deleteFileButtonToolTipText);
|
|
deleteFileButton.setEnabled(false);
|
|
topButtonPanel.add(deleteFileButton);
|
|
|
|
RenameFileAction rfa = new RenameFileAction();
|
|
JButton renameFileButton = new JButton(rfa);
|
|
if (readOnly) {
|
|
rfa.setEnabled(false);
|
|
}
|
|
renameFileButton.setText(renameFileButtonText);
|
|
renameFileButton.setName("GTKFileChooser.renameFileButton");
|
|
renameFileButton.setMnemonic(renameFileButtonMnemonic);
|
|
renameFileButton.setToolTipText(renameFileButtonToolTipText);
|
|
topButtonPanel.add(renameFileButton);
|
|
|
|
fc.add(topButtonPanel, BorderLayout.NORTH);
|
|
|
|
|
|
JPanel interior = new JPanel();
|
|
interior.setBorder(new EmptyBorder(0, 10, 10, 10));
|
|
interior.setName("GTKFileChooser.interiorPanel");
|
|
align(interior);
|
|
interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS));
|
|
|
|
fc.add(interior, BorderLayout.CENTER);
|
|
|
|
JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,
|
|
0, 0) {
|
|
public void layoutContainer(Container target) {
|
|
super.layoutContainer(target);
|
|
JComboBox comboBox = directoryComboBox;
|
|
if (comboBox.getWidth() > target.getWidth()) {
|
|
comboBox.setBounds(0, comboBox.getY(), target.getWidth(),
|
|
comboBox.getHeight());
|
|
}
|
|
}
|
|
});
|
|
comboBoxPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
|
|
comboBoxPanel.setName("GTKFileChooser.directoryComboBoxPanel");
|
|
// CurrentDir ComboBox
|
|
directoryComboBoxModel = createDirectoryComboBoxModel(fc);
|
|
directoryComboBox = new JComboBox(directoryComboBoxModel);
|
|
directoryComboBox.setName("GTKFileChooser.directoryComboBox");
|
|
directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" );
|
|
directoryComboBox.addActionListener(directoryComboBoxAction);
|
|
directoryComboBox.setMaximumRowCount(8);
|
|
comboBoxPanel.add(directoryComboBox);
|
|
interior.add(comboBoxPanel);
|
|
|
|
|
|
// CENTER: left, right, accessory
|
|
JPanel centerPanel = new JPanel(new BorderLayout());
|
|
centerPanel.setName("GTKFileChooser.centerPanel");
|
|
|
|
// SPLIT PANEL: left, right
|
|
JSplitPane splitPanel = new JSplitPane();
|
|
splitPanel.setName("GTKFileChooser.splitPanel");
|
|
splitPanel.setDividerLocation((PREF_SIZE.width-8)/2);
|
|
|
|
// left panel - Filter & directoryList
|
|
JPanel leftPanel = new JPanel(new GridBagLayout());
|
|
leftPanel.setName("GTKFileChooser.directoryListPanel");
|
|
|
|
// Add the Directory List
|
|
// Create a label that looks like button (should be a table header)
|
|
TableCellRenderer headerRenderer = new JTableHeader().getDefaultRenderer();
|
|
JLabel directoryListLabel =
|
|
(JLabel)headerRenderer.getTableCellRendererComponent(null, foldersLabelText,
|
|
false, false, 0, 0);
|
|
directoryListLabel.setName("GTKFileChooser.directoryListLabel");
|
|
leftPanel.add(directoryListLabel, new GridBagConstraints(
|
|
0, 0, 1, 1, 1, 0, GridBagConstraints.WEST,
|
|
GridBagConstraints.HORIZONTAL,
|
|
new Insets(0, 0, 0, 0), 0, 0));
|
|
leftPanel.add(createDirectoryList(), new GridBagConstraints(
|
|
0, 1, 1, 1, 1, 1, GridBagConstraints.EAST,
|
|
GridBagConstraints.BOTH,
|
|
new Insets(0, 0, 0, 0), 0, 0));
|
|
directoryListLabel.setDisplayedMnemonic(foldersLabelMnemonic);
|
|
directoryListLabel.setLabelFor(directoryList);
|
|
|
|
// create files list
|
|
rightPanel = new JPanel(new GridBagLayout());
|
|
rightPanel.setName("GTKFileChooser.fileListPanel");
|
|
|
|
headerRenderer = new JTableHeader().getDefaultRenderer();
|
|
JLabel fileListLabel =
|
|
(JLabel)headerRenderer.getTableCellRendererComponent(null, filesLabelText,
|
|
false, false, 0, 0);
|
|
fileListLabel.setName("GTKFileChooser.fileListLabel");
|
|
rightPanel.add(fileListLabel, new GridBagConstraints(
|
|
0, 0, 1, 1, 1, 0, GridBagConstraints.WEST,
|
|
GridBagConstraints.HORIZONTAL,
|
|
new Insets(0, 0, 0, 0), 0, 0));
|
|
rightPanel.add(createFilesList(), new GridBagConstraints(
|
|
0, 1, 1, 1, 1, 1, GridBagConstraints.EAST,
|
|
GridBagConstraints.BOTH,
|
|
new Insets(0, 0, 0, 0), 0, 0));
|
|
fileListLabel.setDisplayedMnemonic(filesLabelMnemonic);
|
|
fileListLabel.setLabelFor(fileList);
|
|
|
|
splitPanel.add(leftPanel, leftToRight ? JSplitPane.LEFT : JSplitPane.RIGHT);
|
|
splitPanel.add(rightPanel, leftToRight ? JSplitPane.RIGHT : JSplitPane.LEFT);
|
|
centerPanel.add(splitPanel, BorderLayout.CENTER);
|
|
|
|
JComponent accessoryPanel = getAccessoryPanel();
|
|
JComponent accessory = fc.getAccessory();
|
|
if (accessoryPanel != null) {
|
|
if (accessory == null) {
|
|
accessoryPanel.setPreferredSize(ZERO_ACC_SIZE);
|
|
accessoryPanel.setMaximumSize(ZERO_ACC_SIZE);
|
|
} else {
|
|
getAccessoryPanel().add(accessory, BorderLayout.CENTER);
|
|
accessoryPanel.setPreferredSize(accessory.getPreferredSize());
|
|
accessoryPanel.setMaximumSize(MAX_SIZE);
|
|
}
|
|
align(accessoryPanel);
|
|
centerPanel.add(accessoryPanel, BorderLayout.AFTER_LINE_ENDS);
|
|
}
|
|
interior.add(centerPanel);
|
|
interior.add(Box.createRigidArea(vstrut10));
|
|
|
|
JPanel pathFieldPanel = new JPanel(new FlowLayout(FlowLayout.LEADING,
|
|
0, 0));
|
|
pathFieldPanel.setBorder(new EmptyBorder(0, 0, 4, 0));
|
|
JLabel pathFieldLabel = new JLabel(pathLabelText);
|
|
pathFieldLabel.setName("GTKFileChooser.pathFieldLabel");
|
|
pathFieldLabel.setDisplayedMnemonic(pathLabelMnemonic);
|
|
align(pathFieldLabel);
|
|
pathFieldPanel.add(pathFieldLabel);
|
|
pathFieldPanel.add(Box.createRigidArea(hstrut3));
|
|
|
|
File currentDirectory = fc.getCurrentDirectory();
|
|
String curDirName = null;
|
|
if (currentDirectory != null) {
|
|
curDirName = currentDirectory.getPath();
|
|
}
|
|
pathField = new JLabel(curDirName) {
|
|
public Dimension getMaximumSize() {
|
|
Dimension d = super.getMaximumSize();
|
|
d.height = getPreferredSize().height;
|
|
return d;
|
|
}
|
|
};
|
|
pathField.setName("GTKFileChooser.pathField");
|
|
align(pathField);
|
|
pathFieldPanel.add(pathField);
|
|
interior.add(pathFieldPanel);
|
|
|
|
// add the fileName field
|
|
fileNameTextField = new JTextField() {
|
|
public Dimension getMaximumSize() {
|
|
Dimension d = super.getMaximumSize();
|
|
d.height = getPreferredSize().height;
|
|
return d;
|
|
}
|
|
};
|
|
|
|
pathFieldLabel.setLabelFor(fileNameTextField);
|
|
|
|
Set<AWTKeyStroke> forwardTraversalKeys = fileNameTextField.getFocusTraversalKeys(
|
|
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
|
|
forwardTraversalKeys = new HashSet<AWTKeyStroke>(forwardTraversalKeys);
|
|
forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
|
|
fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys);
|
|
|
|
fileNameTextField.setName("GTKFileChooser.fileNameTextField");
|
|
fileNameTextField.getActionMap().put("fileNameCompletionAction", getFileNameCompletionAction());
|
|
fileNameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "fileNameCompletionAction");
|
|
interior.add(fileNameTextField);
|
|
|
|
// Add the filter combo box
|
|
JPanel panel = new JPanel();
|
|
panel.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
|
|
panel.setBorder(new EmptyBorder(0, 0, 4, 0));
|
|
JLabel filterLabel = new JLabel(filterLabelText);
|
|
filterLabel.setName("GTKFileChooser.filterLabel");
|
|
filterLabel.setDisplayedMnemonic(filterLabelMnemonic);
|
|
panel.add(filterLabel);
|
|
|
|
filterComboBoxModel = createFilterComboBoxModel();
|
|
fc.addPropertyChangeListener(filterComboBoxModel);
|
|
filterComboBox = new JComboBox(filterComboBoxModel);
|
|
filterComboBox.setRenderer(createFilterComboBoxRenderer());
|
|
filterLabel.setLabelFor(filterComboBox);
|
|
|
|
interior.add(Box.createRigidArea(vstrut10));
|
|
interior.add(panel);
|
|
interior.add(filterComboBox);
|
|
|
|
// Add buttons
|
|
bottomButtonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
|
|
bottomButtonPanel.setName("GTKFileChooser.bottomButtonPanel");
|
|
align(bottomButtonPanel);
|
|
|
|
JPanel pnButtons = new JPanel(new GridLayout(1, 2, 5, 0));
|
|
|
|
JButton cancelButton = getCancelButton(fc);
|
|
align(cancelButton);
|
|
cancelButton.setMargin(buttonMargin);
|
|
pnButtons.add(cancelButton);
|
|
|
|
JButton approveButton = getApproveButton(fc);
|
|
align(approveButton);
|
|
approveButton.setMargin(buttonMargin);
|
|
pnButtons.add(approveButton);
|
|
|
|
bottomButtonPanel.add(pnButtons);
|
|
|
|
if (fc.getControlButtonsAreShown()) {
|
|
fc.add(bottomButtonPanel, BorderLayout.SOUTH);
|
|
}
|
|
}
|
|
|
|
protected void installListeners(JFileChooser fc) {
|
|
super.installListeners(fc);
|
|
|
|
gtkFCPropertyChangeListener = new GTKFCPropertyChangeListener();
|
|
fc.addPropertyChangeListener(gtkFCPropertyChangeListener);
|
|
}
|
|
|
|
private int getMnemonic(String key, Locale l) {
|
|
return SwingUtilities2.getUIDefaultsInt(key, l);
|
|
}
|
|
|
|
protected void uninstallListeners(JFileChooser fc) {
|
|
super.uninstallListeners(fc);
|
|
|
|
if (gtkFCPropertyChangeListener != null) {
|
|
fc.removePropertyChangeListener(gtkFCPropertyChangeListener);
|
|
}
|
|
}
|
|
|
|
private class GTKFCPropertyChangeListener implements PropertyChangeListener {
|
|
public void propertyChange(PropertyChangeEvent e) {
|
|
String prop = e.getPropertyName();
|
|
if (prop.equals("GTKFileChooser.showDirectoryIcons")) {
|
|
showDirectoryIcons = Boolean.TRUE.equals(e.getNewValue());
|
|
} else if (prop.equals("GTKFileChooser.showFileIcons")) {
|
|
showFileIcons = Boolean.TRUE.equals(e.getNewValue());
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void installDefaults(JFileChooser fc) {
|
|
super.installDefaults(fc);
|
|
readOnly = UIManager.getBoolean("FileChooser.readOnly");
|
|
showDirectoryIcons =
|
|
Boolean.TRUE.equals(fc.getClientProperty("GTKFileChooser.showDirectoryIcons"));
|
|
showFileIcons =
|
|
Boolean.TRUE.equals(fc.getClientProperty("GTKFileChooser.showFileIcons"));
|
|
}
|
|
|
|
protected void installIcons(JFileChooser fc) {
|
|
directoryIcon = UIManager.getIcon("FileView.directoryIcon");
|
|
fileIcon = UIManager.getIcon("FileView.fileIcon");
|
|
}
|
|
|
|
protected void installStrings(JFileChooser fc) {
|
|
super.installStrings(fc);
|
|
|
|
Locale l = fc.getLocale();
|
|
|
|
newFolderDialogText = UIManager.getString("FileChooser.newFolderDialogText", l);
|
|
newFolderErrorText = UIManager.getString("FileChooser.newFolderErrorText",l);
|
|
newFolderErrorSeparator = UIManager.getString("FileChooser.newFolderErrorSeparator",l);
|
|
newFolderButtonText = UIManager.getString("FileChooser.newFolderButtonText", l);
|
|
newFolderNoDirectoryErrorTitleText = UIManager.getString("FileChooser.newFolderNoDirectoryErrorTitleText", l);
|
|
newFolderNoDirectoryErrorText = UIManager.getString("FileChooser.newFolderNoDirectoryErrorText", l);
|
|
deleteFileButtonText = UIManager.getString("FileChooser.deleteFileButtonText", l);
|
|
renameFileButtonText = UIManager.getString("FileChooser.renameFileButtonText", l);
|
|
|
|
newFolderButtonMnemonic = getMnemonic("FileChooser.newFolderButtonMnemonic", l);
|
|
deleteFileButtonMnemonic = getMnemonic("FileChooser.deleteFileButtonMnemonic", l);
|
|
renameFileButtonMnemonic = getMnemonic("FileChooser.renameFileButtonMnemonic", l);
|
|
|
|
newFolderButtonToolTipText = UIManager.getString("FileChooser.newFolderButtonToolTipText", l);
|
|
deleteFileButtonToolTipText = UIManager.getString("FileChooser.deleteFileButtonToolTipText", l);
|
|
renameFileButtonToolTipText = UIManager.getString("FileChooser.renameFileButtonToolTipText", l);
|
|
|
|
renameFileDialogText = UIManager.getString("FileChooser.renameFileDialogText", l);
|
|
renameFileErrorTitle = UIManager.getString("FileChooser.renameFileErrorTitle", l);
|
|
renameFileErrorText = UIManager.getString("FileChooser.renameFileErrorText", l);
|
|
|
|
foldersLabelText = UIManager.getString("FileChooser.foldersLabelText",l);
|
|
foldersLabelMnemonic = getMnemonic("FileChooser.foldersLabelMnemonic", l);
|
|
|
|
filesLabelText = UIManager.getString("FileChooser.filesLabelText",l);
|
|
filesLabelMnemonic = getMnemonic("FileChooser.filesLabelMnemonic", l);
|
|
|
|
pathLabelText = UIManager.getString("FileChooser.pathLabelText",l);
|
|
pathLabelMnemonic = getMnemonic("FileChooser.pathLabelMnemonic", l);
|
|
|
|
filterLabelText = UIManager.getString("FileChooser.filterLabelText", l);
|
|
filterLabelMnemonic = UIManager.getInt("FileChooser.filterLabelMnemonic");
|
|
}
|
|
|
|
protected void uninstallStrings(JFileChooser fc) {
|
|
super.uninstallStrings(fc);
|
|
|
|
newFolderButtonText = null;
|
|
deleteFileButtonText = null;
|
|
renameFileButtonText = null;
|
|
|
|
newFolderButtonToolTipText = null;
|
|
deleteFileButtonToolTipText = null;
|
|
renameFileButtonToolTipText = null;
|
|
|
|
renameFileDialogText = null;
|
|
renameFileErrorTitle = null;
|
|
renameFileErrorText = null;
|
|
|
|
foldersLabelText = null;
|
|
filesLabelText = null;
|
|
|
|
pathLabelText = null;
|
|
|
|
newFolderDialogText = null;
|
|
newFolderErrorText = null;
|
|
newFolderErrorSeparator = null;
|
|
}
|
|
|
|
protected JScrollPane createFilesList() {
|
|
fileList = new JList();
|
|
fileList.setName("GTKFileChooser.fileList");
|
|
fileList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesLabelText);
|
|
|
|
if (getFileChooser().isMultiSelectionEnabled()) {
|
|
fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
|
} else {
|
|
fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
}
|
|
|
|
fileList.setModel(new GTKFileListModel());
|
|
fileList.getSelectionModel().removeSelectionInterval(0, 0);
|
|
fileList.setCellRenderer(new FileCellRenderer());
|
|
fileList.addListSelectionListener(createListSelectionListener(getFileChooser()));
|
|
fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList));
|
|
align(fileList);
|
|
JScrollPane scrollpane = new JScrollPane(fileList);
|
|
scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
|
|
scrollpane.setName("GTKFileChooser.fileListScrollPane");
|
|
scrollpane.setPreferredSize(prefListSize);
|
|
scrollpane.setMaximumSize(MAX_SIZE);
|
|
align(scrollpane);
|
|
return scrollpane;
|
|
}
|
|
|
|
protected JScrollPane createDirectoryList() {
|
|
directoryList = new JList();
|
|
directoryList.setName("GTKFileChooser.directoryList");
|
|
directoryList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, foldersLabelText);
|
|
align(directoryList);
|
|
|
|
directoryList.setCellRenderer(new DirectoryCellRenderer());
|
|
directoryListModel = new GTKDirectoryListModel();
|
|
directoryList.getSelectionModel().removeSelectionInterval(0, 0);
|
|
directoryList.setModel(directoryListModel);
|
|
directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList));
|
|
directoryList.addListSelectionListener(createListSelectionListener(getFileChooser()));
|
|
|
|
JScrollPane scrollpane = new JScrollPane(directoryList);
|
|
scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
|
|
scrollpane.setName("GTKFileChooser.directoryListScrollPane");
|
|
scrollpane.setMaximumSize(MAX_SIZE);
|
|
scrollpane.setPreferredSize(prefListSize);
|
|
align(scrollpane);
|
|
return scrollpane;
|
|
}
|
|
|
|
protected void createModel() {
|
|
model = new GTKDirectoryModel();
|
|
}
|
|
|
|
public BasicDirectoryModel getModel() {
|
|
return model;
|
|
}
|
|
|
|
public Action getApproveSelectionAction() {
|
|
return approveSelectionAction;
|
|
}
|
|
|
|
private class GTKDirectoryModel extends BasicDirectoryModel {
|
|
FileSystemView fsv;
|
|
private Comparator<File> fileComparator = new Comparator<File>() {
|
|
public int compare(File o, File o1) {
|
|
return fsv.getSystemDisplayName(o).compareTo(fsv.getSystemDisplayName(o1));
|
|
}
|
|
};
|
|
|
|
public GTKDirectoryModel() {
|
|
super(getFileChooser());
|
|
}
|
|
|
|
protected void sort(Vector<? extends File> v) {
|
|
fsv = getFileChooser().getFileSystemView();
|
|
Collections.sort(v, fileComparator);
|
|
}
|
|
}
|
|
|
|
protected class GTKDirectoryListModel extends AbstractListModel implements ListDataListener {
|
|
File curDir;
|
|
public GTKDirectoryListModel() {
|
|
getModel().addListDataListener(this);
|
|
directoryChanged();
|
|
}
|
|
|
|
public int getSize() {
|
|
return getModel().getDirectories().size() + 1;
|
|
}
|
|
|
|
public Object getElementAt(int index) {
|
|
return index > 0 ? getModel().getDirectories().elementAt(index - 1):
|
|
curDir;
|
|
}
|
|
|
|
public void intervalAdded(ListDataEvent e) {
|
|
fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
|
|
}
|
|
|
|
public void intervalRemoved(ListDataEvent e) {
|
|
fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
|
|
}
|
|
|
|
// PENDING - this is inefficient - should sent out
|
|
// incremental adjustment values instead of saying that the
|
|
// whole list has changed.
|
|
public void fireContentsChanged() {
|
|
fireContentsChanged(this, 0, getModel().getDirectories().size()-1);
|
|
}
|
|
|
|
// PENDING - fire the correct interval changed - currently sending
|
|
// out that everything has changed
|
|
public void contentsChanged(ListDataEvent e) {
|
|
fireContentsChanged();
|
|
}
|
|
|
|
private void directoryChanged() {
|
|
curDir = getFileChooser().getFileSystemView().createFileObject(
|
|
getFileChooser().getCurrentDirectory(), ".");
|
|
}
|
|
}
|
|
|
|
protected class GTKFileListModel extends AbstractListModel implements ListDataListener {
|
|
public GTKFileListModel() {
|
|
getModel().addListDataListener(this);
|
|
}
|
|
|
|
public int getSize() {
|
|
return getModel().getFiles().size();
|
|
}
|
|
|
|
public boolean contains(Object o) {
|
|
return getModel().getFiles().contains(o);
|
|
}
|
|
|
|
public int indexOf(Object o) {
|
|
return getModel().getFiles().indexOf(o);
|
|
}
|
|
|
|
public Object getElementAt(int index) {
|
|
return getModel().getFiles().elementAt(index);
|
|
}
|
|
|
|
public void intervalAdded(ListDataEvent e) {
|
|
fireIntervalAdded(this, e.getIndex0(), e.getIndex1());
|
|
}
|
|
|
|
public void intervalRemoved(ListDataEvent e) {
|
|
fireIntervalRemoved(this, e.getIndex0(), e.getIndex1());
|
|
}
|
|
|
|
// PENDING - this is inefficient - should sent out
|
|
// incremental adjustment values instead of saying that the
|
|
// whole list has changed.
|
|
public void fireContentsChanged() {
|
|
fireContentsChanged(this, 0, getModel().getFiles().size()-1);
|
|
}
|
|
|
|
// PENDING - fire the interval changed
|
|
public void contentsChanged(ListDataEvent e) {
|
|
fireContentsChanged();
|
|
}
|
|
}
|
|
|
|
|
|
protected class FileCellRenderer extends DefaultListCellRenderer {
|
|
public Component getListCellRendererComponent(JList list, Object value, int index,
|
|
boolean isSelected, boolean cellHasFocus) {
|
|
|
|
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
|
setText(getFileChooser().getName((File) value));
|
|
if (showFileIcons) {
|
|
setIcon(getFileChooser().getIcon((File)value));
|
|
}
|
|
return this;
|
|
}
|
|
}
|
|
|
|
protected class DirectoryCellRenderer extends DefaultListCellRenderer {
|
|
public Component getListCellRendererComponent(JList list, Object value, int index,
|
|
boolean isSelected, boolean cellHasFocus) {
|
|
|
|
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
|
|
|
if (showDirectoryIcons) {
|
|
setIcon(getFileChooser().getIcon((File)value));
|
|
setText(getFileChooser().getName((File)value));
|
|
} else {
|
|
setText(getFileChooser().getName((File)value) + "/");
|
|
}
|
|
return this;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Dimension getPreferredSize(JComponent c) {
|
|
Dimension prefSize = new Dimension(PREF_SIZE);
|
|
JComponent accessory = getFileChooser().getAccessory();
|
|
if (accessory != null) {
|
|
prefSize.width += accessory.getPreferredSize().width + 20;
|
|
}
|
|
Dimension d = c.getLayout().preferredLayoutSize(c);
|
|
if (d != null) {
|
|
return new Dimension(d.width < prefSize.width ? prefSize.width : d.width,
|
|
d.height < prefSize.height ? prefSize.height : d.height);
|
|
} else {
|
|
return prefSize;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Dimension getMinimumSize(JComponent x) {
|
|
return new Dimension(MIN_WIDTH, MIN_HEIGHT);
|
|
}
|
|
|
|
@Override
|
|
public Dimension getMaximumSize(JComponent x) {
|
|
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
|
|
}
|
|
|
|
protected void align(JComponent c) {
|
|
c.setAlignmentX(JComponent.LEFT_ALIGNMENT);
|
|
c.setAlignmentY(JComponent.TOP_ALIGNMENT);
|
|
}
|
|
|
|
public Action getNewFolderAction() {
|
|
if (newFolderAction == null) {
|
|
newFolderAction = new NewFolderAction();
|
|
newFolderAction.setEnabled(!readOnly);
|
|
}
|
|
return newFolderAction;
|
|
}
|
|
|
|
//
|
|
// DataModel for DirectoryComboxbox
|
|
//
|
|
protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) {
|
|
return new DirectoryComboBoxModel();
|
|
}
|
|
|
|
/**
|
|
* Data model for a type-face selection combo-box.
|
|
*/
|
|
protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
|
|
Vector<File> directories = new Vector<File>();
|
|
File selectedDirectory = null;
|
|
JFileChooser chooser = getFileChooser();
|
|
FileSystemView fsv = chooser.getFileSystemView();
|
|
|
|
public DirectoryComboBoxModel() {
|
|
// Add the current directory to the model, and make it the
|
|
// selectedDirectory
|
|
File dir = getFileChooser().getCurrentDirectory();
|
|
if (dir != null) {
|
|
addItem(dir);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds the directory to the model and sets it to be selected,
|
|
* additionally clears out the previous selected directory and
|
|
* the paths leading up to it, if any.
|
|
*/
|
|
private void addItem(File directory) {
|
|
|
|
if (directory == null) {
|
|
return;
|
|
}
|
|
|
|
int oldSize = directories.size();
|
|
directories.clear();
|
|
if (oldSize > 0) {
|
|
fireIntervalRemoved(this, 0, oldSize);
|
|
}
|
|
|
|
// Get the canonical (full) path. This has the side
|
|
// benefit of removing extraneous chars from the path,
|
|
// for example /foo/bar/ becomes /foo/bar
|
|
File canonical;
|
|
try {
|
|
canonical = fsv.createFileObject(ShellFolder.getNormalizedFile(directory).getPath());
|
|
} catch (IOException e) {
|
|
// Maybe drive is not ready. Can't abort here.
|
|
canonical = directory;
|
|
}
|
|
|
|
// create File instances of each directory leading up to the top
|
|
File f = canonical;
|
|
do {
|
|
directories.add(f);
|
|
} while ((f = f.getParentFile()) != null);
|
|
int newSize = directories.size();
|
|
if (newSize > 0) {
|
|
fireIntervalAdded(this, 0, newSize);
|
|
}
|
|
setSelectedItem(canonical);
|
|
}
|
|
|
|
public void setSelectedItem(Object selectedDirectory) {
|
|
this.selectedDirectory = (File)selectedDirectory;
|
|
fireContentsChanged(this, -1, -1);
|
|
}
|
|
|
|
public Object getSelectedItem() {
|
|
return selectedDirectory;
|
|
}
|
|
|
|
public int getSize() {
|
|
return directories.size();
|
|
}
|
|
|
|
public Object getElementAt(int index) {
|
|
return directories.elementAt(index);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Acts when DirectoryComboBox has changed the selected item.
|
|
*/
|
|
protected class DirectoryComboBoxAction extends AbstractAction {
|
|
protected DirectoryComboBoxAction() {
|
|
super("DirectoryComboBoxAction");
|
|
}
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
File f = (File)directoryComboBox.getSelectedItem();
|
|
getFileChooser().setCurrentDirectory(f);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a new folder.
|
|
*/
|
|
private class NewFolderAction extends AbstractAction {
|
|
protected NewFolderAction() {
|
|
super(FilePane.ACTION_NEW_FOLDER);
|
|
}
|
|
public void actionPerformed(ActionEvent e) {
|
|
if (readOnly) {
|
|
return;
|
|
}
|
|
JFileChooser fc = getFileChooser();
|
|
File currentDirectory = fc.getCurrentDirectory();
|
|
String dirName = JOptionPane.showInputDialog(fc,
|
|
newFolderDialogText, newFolderButtonText,
|
|
JOptionPane.PLAIN_MESSAGE);
|
|
|
|
if (dirName != null) {
|
|
if (!currentDirectory.exists()) {
|
|
JOptionPane.showMessageDialog(fc,
|
|
MessageFormat.format(newFolderNoDirectoryErrorText, dirName),
|
|
newFolderNoDirectoryErrorTitleText, JOptionPane.ERROR_MESSAGE);
|
|
return;
|
|
}
|
|
|
|
File newDir = fc.getFileSystemView().createFileObject
|
|
(currentDirectory, dirName);
|
|
if (newDir == null || !newDir.mkdir()) {
|
|
JOptionPane.showMessageDialog(fc,
|
|
newFolderErrorText + newFolderErrorSeparator + " \"" +
|
|
dirName + "\"",
|
|
newFolderErrorText, JOptionPane.ERROR_MESSAGE);
|
|
}
|
|
fc.rescanCurrentDirectory();
|
|
}
|
|
}
|
|
}
|
|
|
|
private class GTKApproveSelectionAction extends ApproveSelectionAction {
|
|
public void actionPerformed(ActionEvent e) {
|
|
if (isDirectorySelected()) {
|
|
File dir = getDirectory();
|
|
try {
|
|
// Strip trailing ".."
|
|
if (dir != null) {
|
|
dir = ShellFolder.getNormalizedFile(dir);
|
|
}
|
|
} catch (IOException ex) {
|
|
// Ok, use f as is
|
|
}
|
|
if (getFileChooser().getCurrentDirectory().equals(dir)) {
|
|
directoryList.clearSelection();
|
|
fileList.clearSelection();
|
|
ListSelectionModel sm = fileList.getSelectionModel();
|
|
if (sm instanceof DefaultListSelectionModel) {
|
|
((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0);
|
|
sm.setAnchorSelectionIndex(0);
|
|
}
|
|
rescanCurrentDirectory(getFileChooser());
|
|
return;
|
|
}
|
|
}
|
|
super.actionPerformed(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renames file
|
|
*/
|
|
private class RenameFileAction extends AbstractAction {
|
|
protected RenameFileAction() {
|
|
super(FilePane.ACTION_EDIT_FILE_NAME);
|
|
}
|
|
public void actionPerformed(ActionEvent e) {
|
|
if (getFileName().equals("")) {
|
|
return;
|
|
}
|
|
JFileChooser fc = getFileChooser();
|
|
File currentDirectory = fc.getCurrentDirectory();
|
|
String newFileName = (String) JOptionPane.showInputDialog
|
|
(fc, new MessageFormat(renameFileDialogText).format
|
|
(new Object[] { getFileName() }),
|
|
renameFileButtonText, JOptionPane.PLAIN_MESSAGE, null, null,
|
|
getFileName());
|
|
|
|
if (newFileName != null) {
|
|
File oldFile = fc.getFileSystemView().createFileObject
|
|
(currentDirectory, getFileName());
|
|
File newFile = fc.getFileSystemView().createFileObject
|
|
(currentDirectory, newFileName);
|
|
if (oldFile == null || newFile == null ||
|
|
!getModel().renameFile(oldFile, newFile)) {
|
|
JOptionPane.showMessageDialog(fc,
|
|
new MessageFormat(renameFileErrorText).
|
|
format(new Object[] { getFileName(), newFileName}),
|
|
renameFileErrorTitle, JOptionPane.ERROR_MESSAGE);
|
|
} else {
|
|
setFileName(getFileChooser().getName(newFile));
|
|
fc.rescanCurrentDirectory();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Renderer for Filter ComboBox
|
|
//
|
|
protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
|
|
return new FilterComboBoxRenderer();
|
|
}
|
|
|
|
/**
|
|
* Render different filters
|
|
*/
|
|
public class FilterComboBoxRenderer extends DefaultListCellRenderer {
|
|
public String getName() {
|
|
// As SynthComboBoxRenderer's are asked for a size BEFORE they
|
|
// are parented getName is overriden to force the name to be
|
|
// ComboBox.renderer if it isn't set. If we didn't do this the
|
|
// wrong style could be used for size calculations.
|
|
String name = super.getName();
|
|
if (name == null) {
|
|
return "ComboBox.renderer";
|
|
}
|
|
return name;
|
|
}
|
|
|
|
public Component getListCellRendererComponent(JList list, Object value,
|
|
int index, boolean isSelected,
|
|
boolean cellHasFocus) {
|
|
|
|
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
|
|
|
setName("ComboBox.listRenderer");
|
|
|
|
if (value != null) {
|
|
if (value instanceof FileFilter) {
|
|
setText(((FileFilter) value).getDescription());
|
|
}
|
|
} else {
|
|
setText("");
|
|
}
|
|
|
|
return this;
|
|
}
|
|
}
|
|
|
|
//
|
|
// DataModel for Filter Combobox
|
|
//
|
|
protected FilterComboBoxModel createFilterComboBoxModel() {
|
|
return new FilterComboBoxModel();
|
|
}
|
|
|
|
/**
|
|
* Data model for filter combo-box.
|
|
*/
|
|
protected class FilterComboBoxModel extends AbstractListModel
|
|
implements ComboBoxModel, PropertyChangeListener {
|
|
protected FileFilter[] filters;
|
|
|
|
protected FilterComboBoxModel() {
|
|
super();
|
|
filters = getFileChooser().getChoosableFileFilters();
|
|
}
|
|
|
|
public void propertyChange(PropertyChangeEvent e) {
|
|
String prop = e.getPropertyName();
|
|
if (prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
|
|
filters = (FileFilter[]) e.getNewValue();
|
|
fireContentsChanged(this, -1, -1);
|
|
} else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
|
|
fireContentsChanged(this, -1, -1);
|
|
}
|
|
}
|
|
|
|
public void setSelectedItem(Object filter) {
|
|
if (filter != null) {
|
|
getFileChooser().setFileFilter((FileFilter) filter);
|
|
fireContentsChanged(this, -1, -1);
|
|
}
|
|
}
|
|
|
|
public Object getSelectedItem() {
|
|
// Ensure that the current filter is in the list.
|
|
// NOTE: we shouldnt' have to do this, since JFileChooser adds
|
|
// the filter to the choosable filters list when the filter
|
|
// is set. Lets be paranoid just in case someone overrides
|
|
// setFileFilter in JFileChooser.
|
|
FileFilter currentFilter = getFileChooser().getFileFilter();
|
|
boolean found = false;
|
|
if (currentFilter != null) {
|
|
for (FileFilter filter : filters) {
|
|
if (filter == currentFilter) {
|
|
found = true;
|
|
}
|
|
}
|
|
if (found == false) {
|
|
getFileChooser().addChoosableFileFilter(currentFilter);
|
|
}
|
|
}
|
|
return getFileChooser().getFileFilter();
|
|
}
|
|
|
|
public int getSize() {
|
|
if (filters != null) {
|
|
return filters.length;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public Object getElementAt(int index) {
|
|
if (index > getSize() - 1) {
|
|
// This shouldn't happen. Try to recover gracefully.
|
|
return getFileChooser().getFileFilter();
|
|
}
|
|
if (filters != null) {
|
|
return filters[index];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|