001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Dmitry A. Durnev
019: * @version $Revision$
020: */package org.apache.harmony.awt.theme;
021:
022: import java.awt.*;
023:
024: import java.awt.event.ActionEvent;
025: import java.awt.event.ActionListener;
026: import java.awt.event.ItemEvent;
027: import java.awt.event.ItemListener;
028: import java.io.File;
029:
030: import org.apache.harmony.awt.ChoiceStyle;
031: import org.apache.harmony.awt.ComponentInternals;
032:
033: /**
034: * DefaultFileDialog
035: * Pure Java Implementation of FileDialog
036: * for platforms where native file dialog
037: * is not used.
038: */
039: public class DefaultFileDialog implements ActionListener, ItemListener {
040: final static int SIZE = 400;
041: final static Insets BORDER = new Insets(2, 4, 2, 4);
042: private final FileDialog fileDialog;
043: boolean shown;
044:
045: List folders;
046: List files;
047: TextField path;
048: TextField filter;
049: TextField fileName;
050: Button okButton;
051: Button filterButton;
052: Button cancelButton;
053: Choice dirChoice;
054:
055: String filterStr;
056:
057: class Separator extends Canvas {
058: private static final long serialVersionUID = -9191946485695242726L;
059:
060: @Override
061: public void paint(Graphics g) {
062: g.setColor(SystemColor.controlDkShadow);
063: g.drawLine(0, 0, getWidth(), 0);
064: g.setColor(SystemColor.controlHighlight);
065: g.drawLine(0, 1, getWidth(), 1);
066: }
067: }
068:
069: public DefaultFileDialog(FileDialog fd) {
070: fileDialog = fd;
071: filterStr = "*"; //$NON-NLS-1$
072: }
073:
074: public void actionPerformed(ActionEvent e) {
075: Object src = e.getSource();
076:
077: if (src == cancelButton) {
078: fileDialog.dispose();
079: } else if (src == folders) {
080: processFolderAction();
081: } else if ((src == files) || (src == okButton)
082: || (src == fileName)) {
083: selectAndClose();
084: } else if (src == path) {
085: String absPath = path.getText();
086: File file = new File(absPath);
087: resetFilter();
088: changeDirectory(file);
089: fillChoice();
090: } else if ((src == filter) || (src == filterButton)) {
091: fillLists();
092: }
093: // TODO handle other actions here:
094:
095: }
096:
097: private void processFolderAction() {
098: int idx = folders.getSelectedIndex();
099: File newFolder = new File(path.getText());
100: if (idx > 0) {
101: newFolder = new File(newFolder, folders.getItem(idx));
102: dirChoice.insert(newFolder.getAbsolutePath(), 0);
103: } else {
104: newFolder = newFolder.getParentFile();
105: if (newFolder != null) {
106: dirChoice.remove(0);
107: }
108: }
109: changeDirectory(newFolder);
110: files.requestFocus();
111: }
112:
113: private void selectAndClose() {
114: String fName = fileName.getText();
115: File folder = new File(path.getText());
116: if (fName.endsWith(File.separator)) {
117: //this is a directory
118: fName = null;
119: } else {
120: File file = new File(fName);
121: fName = file.getName();
122: }
123: fileDialog.setFile(fName);
124: fileDialog.setDirectory(folder.getAbsolutePath());
125: fileDialog.dispose();
126: }
127:
128: private void changeDirectory(File file) {
129: if ((file == null) || !file.isDirectory()) {
130: return;
131: }
132: String absPath = file.getAbsolutePath();
133: String fName = absPath;
134: String sep = File.separator;
135: if (!fName.endsWith(sep)) {
136: fName += sep;
137: }
138: fileName.setText(fName);
139: path.setText(absPath);
140: fillLists();
141:
142: }
143:
144: public void itemStateChanged(ItemEvent e) {
145: Object src = e.getSource();
146: if (src == files) {
147: fileName.setText(files.getSelectedItem());
148: } else if (src == dirChoice) {
149: resetFilter();
150: changeDirectory(new File(dirChoice.getSelectedItem()));
151: int selIdx = dirChoice.getSelectedIndex();
152: for (int i = 0; i < selIdx; i++) {
153: dirChoice.remove(0);
154: }
155: path.requestFocus();
156: }
157: }
158:
159: public boolean show() {
160: if (!shown) {
161: fileDialog.setBackground(SystemColor.control);
162: // create components & add listeners here
163: createComponents();
164: addLayoutComponents();
165: addListeners();
166: fileDialog.setSize(SIZE, SIZE);
167: String file = fileDialog.getFile();
168: File curFile = ((file != null) ? new File(file) : null);
169: File curFolder = ((curFile != null) ? curFile
170: .getParentFile() : getDefaultFolder());
171: changeDirectory(curFolder);
172: if (curFile != null) {
173: fileName.setText(file);
174: }
175: fillChoice();
176: shown = true;
177: }
178: return true; // call Dialog's show()
179: }
180:
181: private void fillLists() {
182: clearLists();
183: updateFilter();
184: File curFolder = new File(path.getText());
185: if ((curFolder != null) && curFolder.isDirectory()) {
186: File[] allFiles = curFolder.listFiles(fileDialog
187: .getFilenameFilter());
188: int count = allFiles.length;
189: for (int i = 0; i < count; i++) {
190: File f = allFiles[i];
191: String fName = f.getName();
192: if (f.isDirectory()) {
193: folders.add(fName);
194: }
195: if (f.isFile()) {
196: if (applyFilter(fName)) {
197: files.add(fName);
198: }
199: }
200: }
201: }
202: }
203:
204: private boolean applyFilter(String name) {
205: // TODO: apply filter from "filter" text field
206: return name.matches(filterStr);
207: }
208:
209: private void updateFilter() {
210: filterStr = filter.getText().replaceAll("\\.", "\\\\."); //$NON-NLS-1$ //$NON-NLS-2$
211: filterStr = filterStr.replaceAll("\\*", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
212: }
213:
214: private void resetFilter() {
215: filterStr = "*"; //$NON-NLS-1$
216: filter.setText(filterStr);
217: updateFilter();
218: }
219:
220: private void clearLists() {
221: if (folders.getItemCount() > 0) {
222: folders.removeAll();
223: }
224: folders.add(".."); //$NON-NLS-1$
225: if (files.getItemCount() > 0) {
226: files.removeAll();
227: }
228: }
229:
230: private File getDefaultFolder() {
231: return new File(System.getProperty("user.dir")); //$NON-NLS-1$
232: }
233:
234: private void addListeners() {
235: folders.addItemListener(this );
236: folders.addActionListener(this );
237:
238: files.addItemListener(this );
239: files.addActionListener(this );
240: okButton.addActionListener(this );
241: filterButton.addActionListener(this );
242: cancelButton.addActionListener(this );
243: path.addActionListener(this );
244: fileName.addActionListener(this );
245: dirChoice.addItemListener(this );
246: filter.addActionListener(this );
247:
248: }
249:
250: private void createComponents() {
251: path = new TextField();
252: fileName = new TextField();
253: dirChoice = createCustomChoice();
254: filter = new TextField(filterStr);
255: folders = new List();
256: files = new List();
257: okButton = new Button("OK"); //$NON-NLS-1$
258: filterButton = new Button("Filter"); //$NON-NLS-1$
259: cancelButton = new Button("Cancel"); //$NON-NLS-1$
260: }
261:
262: private Choice createCustomChoice() {
263: ChoiceStyle style = new ChoiceStyle() {
264:
265: public int getPopupX(int x, int width, int choiceWidth,
266: int screenWidth) {
267: int popupX = x;
268: if (width > choiceWidth) {
269: popupX -= (width - choiceWidth);
270: }
271: popupX = Math.max(0, popupX);
272: if (popupX + width > screenWidth) {
273: popupX = screenWidth - width;
274: }
275: return popupX;
276: }
277:
278: public int getPopupWidth(int choiceWidth) {
279: int hGap = ((BorderLayout) path.getParent().getLayout())
280: .getHgap();
281: return choiceWidth + path.getWidth() + hGap;
282: }
283:
284: };
285: return ComponentInternals.getComponentInternals()
286: .createCustomChoice(style);
287: }
288:
289: private void addLayoutComponents() {
290: GridBagLayout gbl = new GridBagLayout();
291: GridBagConstraints gbc = new GridBagConstraints();
292: gbc.fill = GridBagConstraints.BOTH;
293: gbc.insets = BORDER;
294: fileDialog.setLayout(gbl);
295:
296: addPath(gbc);
297:
298: fileDialog.add(new Label("Filter"), gbc); //$NON-NLS-1$
299: fileDialog.add(filter, gbc);
300:
301: addLists(gbc);
302:
303: gbc.weighty = 0.0;
304: gbc.weightx = 0.0;
305: fileDialog.add(new Label("Enter file name:"), gbc); //$NON-NLS-1$
306: fileDialog.add(fileName, gbc);
307:
308: Separator sep = new Separator();
309: sep.setMinimumSize(new Dimension(10, 3));
310: gbc.insets = new Insets(2, 0, 2, 0);
311: fileDialog.add(sep, gbc);
312:
313: Panel buttonPanel = new Panel(new GridBagLayout());
314: fileDialog.add(buttonPanel, gbc);
315: addButtons(buttonPanel);
316: }
317:
318: private void addPath(GridBagConstraints gbc) {
319: gbc.weightx = 1.0;
320: gbc.gridwidth = GridBagConstraints.REMAINDER;
321: fileDialog.add(new Label("Enter path or folder name:"), gbc); //$NON-NLS-1$
322: Panel pathPanel = new Panel(new BorderLayout());
323: pathPanel.add(path); // CENTER
324: int cSize = DefaultScrollbar.BUTTON_SIZE + BORDER.top;
325: dirChoice.setPreferredSize(new Dimension(cSize, cSize));
326: pathPanel.add(dirChoice, BorderLayout.EAST);
327: gbc.weightx = 0.0;
328: fileDialog.add(pathPanel, gbc);
329: }
330:
331: private void addLists(GridBagConstraints gbc) {
332: gbc.weightx = 1.0;
333: gbc.gridwidth = 1;
334: fileDialog.add(new Label("Folders"), gbc); //$NON-NLS-1$
335: gbc.gridwidth = GridBagConstraints.REMAINDER;
336: fileDialog.add(new Label("Files"), gbc); //$NON-NLS-1$
337: gbc.gridwidth = 1;
338: gbc.weighty = 1.0;
339: fileDialog.add(folders, gbc);
340: gbc.gridwidth = GridBagConstraints.REMAINDER;
341: fileDialog.add(files, gbc);
342: }
343:
344: private void addButtons(Panel p) {
345: GridBagConstraints gbc = new GridBagConstraints();
346: gbc.weightx = 1.0;
347: gbc.gridwidth = 1;
348: gbc.insets = BORDER;
349: gbc.fill = GridBagConstraints.VERTICAL;
350: gbc.anchor = GridBagConstraints.WEST;
351: p.add(okButton, gbc);
352: gbc.anchor = GridBagConstraints.CENTER;
353: p.add(filterButton, gbc);
354: gbc.anchor = GridBagConstraints.EAST;
355: p.add(cancelButton, gbc);
356: }
357:
358: private void fillChoice() {
359: // fill Choice list with absolute paths
360: dirChoice.removeAll();
361: File folder = new File(path.getText());
362: while ((folder != null) && folder.isDirectory()) {
363: dirChoice.add(folder.getAbsolutePath());
364: folder = folder.getParentFile();
365: }
366: }
367:
368: }
|