blob: f6ea1e4fd69f2bfa615ea4b65ec1dba943621117 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.uima.tools.util.gui;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;
/**
* Composite component to allow file or directory input or selection. Comprises a JTextField, and a
* browse button associated with a JFileChooser.
*/
public class FileSelector extends JPanel implements FocusListener {
private static final long serialVersionUID = -1438950608628876422L;
private JTextField field;
private BrowseButton browseButton;
/**
* Note that fileChooser is created lazily, to address issue UIMA-231. Apparently calls
* to JFileChooser.setCurrentDirectory aren't reliable before the file chooser has been
* shown.
*/
private JFileChooser fileChooser;
private JComponent source;
private FileSelectorListener fileSelectorListener = null;
private String previousValue;
private File initialDir;
private String fileChooserTitle;
private int selectionMode;
private FileFilter filter;
/**
* Creates a new FileSelector.
*
* @param initialValue filename initially displayed in the text field
* @param fileChooserTitle title of the JFileChooser launched when the user clicks Browse
* @param selectionMode Can be either JFileChooser.FILES_ONLY, JFileChooser.DIRECTORIES_ONLY or JFileChooser.FILES_AND_DIRECTORIES
* @param currentDir default directory for the file chooser
*/
public FileSelector(String initialValue, String fileChooserTitle, int selectionMode) //
{
this(initialValue, fileChooserTitle, selectionMode, null);
}
/**
* Creates a new FileSelector.
*
* @param initialValue filename initially displayed in the text field
* @param fileChooserTitle title of the JFileChooser launched when the user clicks Browse
* @param selectionMode Can be either JFileChooser.FILES_ONLY, JFileChooser.DIRECTORIES_ONLY or JFileChooser.FILES_AND_DIRECTORIES
* @param currentDir default directory for the file chooser
*/
public FileSelector(String initialValue, String fileChooserTitle, int selectionMode, File currentDir) {
this(initialValue, fileChooserTitle, selectionMode, currentDir, null);
}
/**
* Creates a new FileSelector.
*
* @param initialValue filename initially displayed in the text field
* @param fileChooserTitle title of the JFileChooser launched when the user clicks Browse
* @param selectionMode Can be either JFileChooser.FILES_ONLY, JFileChooser.DIRECTORIES_ONLY or JFileChooser.FILES_AND_DIRECTORIES
* @param currentDir default directory for the file chooser
* @param filter file filter used by the file chooser
*/
public FileSelector(String initialValue, String fileChooserTitle, int selectionMode, File currentDir,
FileFilter filter) {
if (currentDir == null && initialValue != null) {
currentDir = new File(initialValue).getAbsoluteFile();
}
this.initialDir = currentDir;
this.fileChooserTitle = fileChooserTitle;
this.selectionMode = selectionMode;
this.filter = filter;
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
field = new JTextField(initialValue, 20);
field.addFocusListener(this);
add(field);
previousValue = initialValue == null ? "" : initialValue;
add(Box.createHorizontalStrut(8));
browseButton = new BrowseButton("Browse..");
add(browseButton);
browseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = getFileChooser();
int returnVal = chooser.showOpenDialog(browseButton);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
String fileString = file.getAbsolutePath();
if (fileSelectorListener != null) {
boolean result = fileSelectorListener.fileSelected(source, fileString);
// Only update textField is successful:
if (result == true) // Success
{
field.setText(fileString);
previousValue = fileString;
} else
// Failure - restore previous value:
chooser.setSelectedFile(new File(previousValue));
} else {
field.setText(fileString);
previousValue = fileString;
}
}
}
});
field.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
// did text change?
String fileString = field.getText();
if (!fileString.equals(previousValue)) {
if (fileSelectorListener != null) {
boolean result = fileSelectorListener.fileSelected(source, fileString);
// Only update textField if successful:
if (result == true) // Success
{
previousValue = fileString;
} else
// Failure - restore previous value:
if (fileChooser != null) {
fileChooser.setSelectedFile(previousValue == null ? null : new File(previousValue));
}
} else {
previousValue = fileString;
}
}
}
});
field.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String fileString = field.getText();
if (fileSelectorListener != null) {
String oldValue = previousValue;
// have to set previousValue to new value here to avoid
// focusLost event triggering infinite loop
previousValue = fileString;
boolean result = fileSelectorListener.fileSelected(source, fileString);
if (!result) // undo
{
previousValue = oldValue;
if (fileChooser != null) {
fileChooser.setSelectedFile(previousValue == null ? null : new File(previousValue));
}
}
} else {
previousValue = fileString;
}
}
}
});
}
public void addFileSelectorListener(FileSelectorListener fileSelectorListener, JComponent source) {
this.fileSelectorListener = fileSelectorListener;
this.source = source;
}
public String getSelected() {
return field.getText();
}
public void setSelected(String s) {
field.setText(s);
previousValue = s;
if (s == null || s.length() == 0) {
s = System.getProperty("user.dir");
}
File file = new File(s);
//only modify file chooser if it has already been created
if (this.fileChooser != null) {
if (this.fileChooser.getFileSelectionMode() == JFileChooser.FILES_ONLY && file.isDirectory()) {
this.fileChooser.setCurrentDirectory(file);
} else {
this.fileChooser.setSelectedFile(file);
}
}
}
public void setEnabled(boolean onOff) {
field.setEnabled(onOff);
browseButton.setEnabled(onOff);
}
public void clear() {
field.setText("");
}
static class BrowseButton extends JButton {
private static final long serialVersionUID = 1086776109494251334L;
public BrowseButton(String s) {
super(s);
}
public Insets getInsets() {
return new Insets(3, 6, 3, 6);
}
}
/*
* (non-Javadoc)
*
* @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
*/
public void focusGained(FocusEvent aEvent) {
}
/*
* (non-Javadoc)
*
* @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
*/
public void focusLost(FocusEvent aEvent) {
if (aEvent.getComponent() == this.field) {
//only modify file chooser if it has already been created
if (this.fileChooser != null) {
String path = this.getSelected();
if (path.length() == 0) {
path = System.getProperty("user.dir");
}
File file = new File(path);
if (this.fileChooser.getFileSelectionMode() == JFileChooser.FILES_ONLY && file.isDirectory()) {
this.fileChooser.setCurrentDirectory(file);
} else {
this.fileChooser.setSelectedFile(file);
}
}
}
}
/**
* Get the File Chooser user when the Browse button is clicked. This is lazily created when
* needed, because of issue UIMA-231.
* @return the file chooser
*/
protected JFileChooser getFileChooser() {
if (this.fileChooser == null) {
String val = field.getText();
final File selected = (val == null) ? null : new File(val);
fileChooser = new JFileChooser(initialDir);
fileChooser.setDialogTitle(fileChooserTitle);
fileChooser.setFileSelectionMode(selectionMode);
if (filter != null) {
fileChooser.addChoosableFileFilter(filter);
}
fileChooser.setSelectedFile(selected);
}
return this.fileChooser;
}
}