Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
In save mode, a confirm dialog is displayed when the selected file
* already exists.
*
Some classical problem are detected while validating the dialog.
*
*
In open mode, the file does not exist.
*
The application have no right to access the file.
*
*
*
The getSelectedFile methods returns the selected file, even if the file
* name field has been modified (It's strange but that method in JFileChooser
* returns the last file selected in the file list until the "ok" button is
* pressed. It sounds like a bug of JFileChooser)
*
setSelectedFile(null) clears the current selection.
*
The SELECTED_FILE_CHANGED_PROPERTY event is thrown accordingly to the
* previous point.
*
* Here is the bad news: This component is designed to allow selection of
* individual files, not folder, not multiple files :-(
*
* @author Jean-Marc Astesana
* License: LGPL v3
*/
public class FileChooser extends JFileChooser {
private static final long serialVersionUID = 1L;
private JTextField fileNameField;
private File selectedFile;
private Component fileNameLabel;
private boolean selectionTestEnabled;
public FileChooser() {
this(null);
}
public FileChooser(String path) {
super(path);
this.selectionTestEnabled = true;
this.selectedFile = null;
fileNameField = null;
try {
Field field = getUI().getClass().getDeclaredField("fileNameTextField"); //$NON-NLS-1$
try {
field.setAccessible(true);
fileNameField = (JTextField) field.get(getUI());
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (NoSuchFieldException e) {
// If there's no fileNameField ... we will suppose there's no
// problem with this field updates !
}
try {
Field field = getUI().getClass().getDeclaredField("fileNameLabel"); //$NON-NLS-1$
try {
field.setAccessible(true);
fileNameLabel = (JLabel) field.get(getUI());
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (NoSuchFieldException e) {
// If there's no fileNameLabel ... ok, then we will not do anything with it !
}
PropertyChangeListener listener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
File old = getSelectedFile();
File superSelected = FileChooser.super.getSelectedFile();
String name = fileNameField != null ? fileNameField.getText() : superSelected==null?"":superSelected.getName();
File selectedFile = buildSelectedFile(name);
if (!NullUtils.areEquals(old, selectedFile)) {
int pos = fileNameField != null ? fileNameField.getCaretPosition() : 0;
firePropertyChange(SELECTED_FILE_CHANGED_PROPERTY, old, selectedFile);
if (fileNameField != null) {
if (pos > fileNameField.getText().length()) {
pos = fileNameField.getText().length();
}
fileNameField.setCaretPosition(pos);
}
}
}
};
if (fileNameField != null) {
new MyDocument(fileNameField);
addPropertyChangeListener(MyDocument.TEXT_PROPERTY, listener);
}
addPropertyChangeListener(DIRECTORY_CHANGED_PROPERTY, listener);
}
@Override
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
// Update the selectedFile attribute
if (SELECTED_FILE_CHANGED_PROPERTY.equals(propertyName)) {
selectedFile = (File) newValue;
}
super.firePropertyChange(propertyName, oldValue, newValue);
}
/** Tests whether the getSelectedFile method is fixed.
* Unfortunately, the original JFileChooser has a bug: getSelectedFile returns a wrong value when
* text is typed in the file name field.
* This class tries to fix it, but the fix is not available under some look and feels (CDE/Motif for example).
* @return true if the bug is fixed for the current look and feel.
*/
public boolean isGetSelectedFileFixed() {
return fileNameField!=null;
}
@Override
public File getSelectedFile() {
// The JFileChooser getSelectedFile returns a wrong value when the file name field is changed
// So, we use an attribute updated when events that modify the selected file occurs ... if we can find it in the UI.
if (!isGetSelectedFileFixed()) {
// If not, we ask the ui ... if it allows it
if (getUI() instanceof BasicFileChooserUI) {
String name = ((BasicFileChooserUI)getUI()).getFileName();
selectedFile = buildSelectedFile(name);
} else {
System.err.println ("Warning, unable to get the current file name. UI is instance of "+ui.getClass());
selectedFile = super.getSelectedFile();
}
}
return selectedFile;
}
@Override
public void approveSelection() {
if (selectionTestEnabled) {
// Refuse:
// The broken links
// The non existing files in OPEN_DIALOG mode
// Non readable/writable files
// Ask what to do if the file exists and we are in SAVE_DIALOG mode
File file = getSelectedFile();
if (file != null) {
if (getDialogType() == SAVE_DIALOG) {
File canonical;
try {
canonical = FileUtils.getCanonical(file);
if (canonical.exists()) {
boolean cancel = showSaveDisplayQuestion(this);
if (cancel) {
// User doesn't want to overwrite the file
return;
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
String error = getDisabledCause();
if (error != null) {
JOptionPane.showMessageDialog(this, error, get("Generic.error"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$
return;
}
}
}
super.approveSelection();
}
/**
* Activate/Deactivate the test made on the selected file during in
* approveSelection method.
* The default value is true.
* @param enabled true to perform tests, false to skip them.
*/
public void setSelectionTestEnabled(boolean enabled) {
this.selectionTestEnabled = enabled;
}
public String getDisabledCause() {
File file = getSelectedFile();
if (file == null) {
return null;
}
try {
if (getDialogType() == OPEN_DIALOG) {
if (!file.exists()) {
return get("openDialog.fileDoesntExist"); //$NON-NLS-1$
} else {
File canonical = FileUtils.getCanonical(file);
if (!canonical.exists()) {
return get("openDialog.targetDoesntExist"); //$NON-NLS-1$
} else if (!FileUtils.isReadable(file)) {
return get("openDialog.fileNotReadable"); //$NON-NLS-1$
}
}
} else {
File canonical = FileUtils.getCanonical(file);
if (!FileUtils.isWritable(canonical)) {
return get("saveDialog.fileNotWritable"); //$NON-NLS-1$
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
private String get(String key) {
return Application.LOCALIZATION.getString(key, getLocale());
}
/**
* Displays a dialog to inform the user that a file is already existing and it
* will be overwritten if the user continue.
*
* @param parent
* determines the Frame in which the dialog is displayed; if null, or
* if the parentComponent has no Frame, a default Frame is used
* @return true if the user cancels
*/
public static boolean showSaveDisplayQuestion(Component parent) {
String message = Application.LOCALIZATION.getString("saveDialog.FileExist.message", parent.getLocale()); //$NON-NLS-1$
return JOptionPane.showOptionDialog(parent, message,
Application.LOCALIZATION.getString("saveDialog.FileExist.title", parent.getLocale()), //$NON-NLS-1$
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null) == JOptionPane.NO_OPTION;
}
/*
* (non-Javadoc)
*
* @see javax.swing.JFileChooser#setDialogType(int)
*/
@Override
public void setDialogType(int dialogType) {
if ((fileNameField != null) && (fileNameLabel != null)) {
boolean visible = dialogType != JFileChooser.OPEN_DIALOG;
fileNameField.setVisible(visible);
fileNameLabel.setVisible(visible);
}
super.setDialogType(dialogType);
}
/*
* (non-Javadoc)
*
* @see javax.swing.JFileChooser#setSelectedFile(java.io.File)
*/
@Override
public void setSelectedFile(File file) {
if ((file == null) && (selectedFile != null)) {
File parent = selectedFile.getParentFile();
super.setSelectedFile(new File("")); //$NON-NLS-1$
super.setCurrentDirectory(parent);
selectedFile = null;
} else {
super.setSelectedFile(file);
}
}
private File buildSelectedFile(String name) {
// We should remove directory because in DIRECTORIES_ONLY selection mode, the directory may be in the file name
name = new File(name).getName();
return name.length() == 0 ? null : new File(FileChooser.super.getCurrentDirectory(), name);
}
private class MyDocument extends PlainDocument {
private static final long serialVersionUID = 1L;
private static final String TEXT_PROPERTY = "text"; //$NON-NLS-1$
private boolean ignoreEvents = false;
private JTextField field;
private MyDocument(JTextField field) {
this.field = field;
field.setDocument(this);
}
@Override
public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
String oldValue = field.getText();
this.ignoreEvents = true;
super.replace(offset, length, text, attrs);
this.ignoreEvents = false;
String newValue = field.getText();
if (!oldValue.equals(newValue)) {
firePropertyChange(TEXT_PROPERTY, oldValue, newValue);
}
}
@Override
public void remove(int offs, int len) throws BadLocationException {
String oldValue = field.getText();
super.remove(offs, len);
String newValue = field.getText();
if (!ignoreEvents && !oldValue.equals(newValue)) {
firePropertyChange(TEXT_PROPERTY, oldValue, newValue);
}
}
}
}