001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.util.swing;
038:
039: import javax.swing.*;
040: import javax.swing.filechooser.FileFilter;
041: import java.awt.*;
042: import java.awt.event.ActionEvent;
043: import java.awt.event.ActionListener;
044: import java.awt.event.FocusListener;
045: import java.awt.event.FocusEvent;
046: import java.io.*;
047:
048: import edu.rice.cs.util.UnexpectedException;
049:
050: /** A JPanel with a text box and a "..." button used to select a file or directory. The file name is editable in the
051: * text box, and a JFileChooser is displayed if the user clicks the "..." button.
052: * TODO: make this inherit from FileSelectorStringComponent or factor the common code into an abstract class! Duplicated code!
053: * @version $Id: FileSelectorComponent.java 4290 2007-12-24 06:57:40Z mgricken $
054: */
055: public class FileSelectorComponent extends JPanel {
056:
057: /** The default number of columns for the text box. */
058: public static final int DEFAULT_NUM_COLS = 30;
059:
060: /** The default font size for the text box. */
061: public static final float DEFAULT_FONT_SIZE = 10f;
062:
063: /** The parent frame of this component. */
064: protected final Frame _parent;
065:
066: /** Text field with the name of the selected file. */
067: protected final JTextField _fileField;
068:
069: /** "..." button to open the file chooser. */
070: protected final JButton _chooserButton;
071:
072: /** File chooser to open when clicking the "..." button. */
073: protected final JFileChooser _chooser;
074:
075: /** File filter to use in the chooser. */
076: protected volatile FileFilter _fileFilter;
077:
078: /** The current file */
079: protected volatile File _file;
080:
081: /** True if file must exist. */
082: protected volatile boolean _mustExist;
083:
084: /** Creates a new FileSelectorComponent with default dimensions.
085: *
086: * @param parent Parent of this component.
087: * @param chooser File chooser to display from the "..." button.
088: */
089: public FileSelectorComponent(Frame parent, JFileChooser chooser) {
090: this (parent, chooser, DEFAULT_NUM_COLS, DEFAULT_FONT_SIZE, true);
091: }
092:
093: /** Creates a new FileSelectorComponent.
094: *
095: * @param parent Parent of this component.
096: * @param chooser File chooser to display from the "..." button.
097: * @param numCols Number of columns to display in the text field
098: * @param fontSize Font size for the text field
099: */
100: public FileSelectorComponent(Frame parent, JFileChooser chooser,
101: int numCols, float fontSize) {
102: this (parent, chooser, numCols, fontSize, true);
103: }
104:
105: /** Creates a new FileSelectorComponent.
106: *
107: * @param parent Parent of this component; may be null if the FileSelector is supposed to stand-alone.
108: * @param chooser File chooser to display from the "..." button.
109: * @param numCols Number of columns to display in the text field
110: * @param fontSize Font size for the text field
111: * @param mustExist force selection of existing file
112: */
113: public FileSelectorComponent(Frame parent, JFileChooser chooser,
114: int numCols, float fontSize, boolean mustExist) {
115:
116: if (chooser == null)
117: throw new UnexpectedException(
118: "Error: called new FileSelectorComponent(...) with a null chooser!");
119:
120: _parent = parent;
121: _chooser = chooser;
122: _fileFilter = null;
123: _mustExist = mustExist;
124:
125: _fileField = new JTextField(numCols) {
126: public Dimension getMaximumSize() {
127: return new Dimension(Short.MAX_VALUE, super
128: .getPreferredSize().height);
129: }
130: };
131:
132: _fileField.setFont(_fileField.getFont().deriveFont(fontSize));
133: _fileField.setPreferredSize(new Dimension(22, 22));
134: _fileField.addActionListener(new ActionListener() {
135: public void actionPerformed(ActionEvent e) {
136: validateTextField();
137: }
138: });
139:
140: _fileField.addFocusListener(new FocusListener() {
141: public void focusGained(FocusEvent e) { /* validateTextField(); */
142: }
143:
144: public void focusLost(FocusEvent e) {
145: validateTextField();
146: }
147: });
148:
149: _chooserButton = new JButton("...");
150: _chooserButton.addActionListener(new ActionListener() {
151: public void actionPerformed(ActionEvent e) {
152: _chooseFile();
153: }
154: });
155:
156: _chooserButton.setMaximumSize(new Dimension(22, 22));
157: _chooserButton.setMargin(new Insets(0, 5, 0, 5));
158:
159: // Add components
160: this .setLayout(new BoxLayout(this , BoxLayout.X_AXIS));
161: this .add(_fileField);
162: this .add(_chooserButton);
163: }
164:
165: public void setEnabled(boolean isEnabled) {
166: _fileField.setEnabled(isEnabled);
167: _chooserButton.setEnabled(isEnabled);
168: super .setEnabled(isEnabled);
169: }
170:
171: /** Returns the file text field. */
172: public JTextField getFileField() {
173: return _fileField;
174: }
175:
176: /** Returns the file chooser. */
177: public JFileChooser getFileChooser() {
178: return _chooser;
179: }
180:
181: /** Returns the file currently typed into the file field. */
182: public File getFileFromField() {
183: String txt = _fileField.getText().trim();
184: if (txt.equals(""))
185: _file = null;
186: else
187: _file = new File(txt);
188:
189: return _file;
190: }
191:
192: /** Sets the text of the file field to be the given file.
193: * @param file File to display in the file field.
194: */
195: public void setFileField(File file) {
196: _file = file;
197: if (file != null && !file.getPath().equals("")) {
198: try {
199: _file = file.getCanonicalFile();
200: } catch (IOException e) { /* do nothing */
201: }
202: }
203: resetFileField();
204: }
205:
206: public void resetFileField() {
207: if (_file == null)
208: _fileField.setText("");
209: else {
210: _fileField.setText(_file.getPath());
211: _fileField.setCaretPosition(_fileField.getText().length());
212: }
213: }
214:
215: /** Sets the file filter to use. */
216: public void setFileFilter(FileFilter filter) {
217: _fileFilter = filter;
218: }
219:
220: public void setToolTipText(String text) {
221: super .setToolTipText(text);
222: _fileField.setToolTipText(text);
223: _chooser.setToolTipText(text);
224: }
225:
226: /** Opens the file chooser to select a file, putting the result in the file field. */
227: private void _chooseFile() {
228: // Set the chooser to be in the right directory
229: if (_file != null && _file.exists()) {
230: _chooser.setCurrentDirectory(_file);
231: _chooser.setSelectedFile(_file);
232: }
233:
234: // Apply the filter
235: if (_fileFilter != null)
236: _chooser.setFileFilter(_fileFilter);
237:
238: // Get the file from the chooser
239: int returnValue = _chooser.showDialog(_parent, null);
240: if (returnValue == JFileChooser.APPROVE_OPTION) {
241: File chosen = _chooser.getSelectedFile();
242: if (chosen != null)
243: setFileField(chosen);
244: }
245: }
246:
247: // used so that the focus listener and the action listener do not
248: // both validate the incorrect text. This ensures that only the first
249: // one gets it.
250: // private boolean _validationInProgress = false;
251:
252: /** The chooser method for the validation of filenames that are manually entered into the text field.
253: * @return False, if file does not exist. True, otherwise.
254: */
255: public boolean validateTextField() {
256: // if (_validationInProgress) return true;
257: // _validationInProgress = true;
258:
259: String newValue = _fileField.getText().trim();
260:
261: File newFile = null;
262: if (!newValue.equals(""))
263: newFile = new File(newValue);
264:
265: if (newFile != null && _mustExist && !newFile.exists()) {
266: JOptionPane.showMessageDialog(_parent, "The file '"
267: + newValue
268: + "'\nis invalid because it does not exist.",
269: "Invalid File Name", JOptionPane.ERROR_MESSAGE);
270: if (_file != null && !_file.exists())
271: _file = null;
272: resetFileField(); // revert if not valid
273:
274: // _validationInProgress = false;
275: return false;
276: } else {
277: setFileField(newFile);
278: // _validationInProgress = false;
279: return true;
280: }
281: }
282: }
|