001: /*
002: * Copyright 2008 Paul Hinds
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.tp23.gui.tree;
017:
018: import java.awt.BorderLayout;
019: import java.awt.Component;
020: import java.awt.FlowLayout;
021: import java.awt.Frame;
022: import java.awt.HeadlessException;
023: import java.awt.event.ActionEvent;
024: import java.awt.event.ActionListener;
025: import java.awt.event.WindowAdapter;
026: import java.awt.event.WindowEvent;
027: import java.io.File;
028: import java.io.FileNotFoundException;
029:
030: import javax.swing.BorderFactory;
031: import javax.swing.JButton;
032: import javax.swing.JDialog;
033: import javax.swing.JFileChooser;
034: import javax.swing.JFrame;
035: import javax.swing.JLabel;
036: import javax.swing.JPanel;
037: import javax.swing.JRootPane;
038: import javax.swing.JScrollPane;
039: import javax.swing.JTextField;
040: import javax.swing.JTree;
041: import javax.swing.SwingUtilities;
042: import javax.swing.event.TreeSelectionEvent;
043: import javax.swing.event.TreeSelectionListener;
044: import javax.swing.filechooser.FileSystemView;
045: import javax.swing.tree.DefaultTreeModel;
046: import javax.swing.tree.TreePath;
047:
048: import org.tp23.antinstaller.renderer.AIResourceBundle;
049: import org.tp23.gui.tree.model.FileSystemModel;
050: import org.tp23.gui.tree.model.ItemModel;
051: import org.tp23.gui.widget.DirectoryChooser;
052:
053: /**
054: * Since the Swing directory chooser does not have a reliable API so select a directory that does not yet exist
055: * this JDialog fills the gap, it does not have all the bells and whistles that the default LookAndFeels directory
056: * chooser might have.
057: *
058: * TODO add a label for the file name field from the current Locale
059: * TODO more widgets from other file choosers
060: * @author teknopaul
061: *
062: */
063: public class CustomDirectoryChooser extends JDialog implements
064: DirectoryChooser {
065:
066: private static final AIResourceBundle res = new AIResourceBundle();
067:
068: private JScrollPane jScrollPane1 = new JScrollPane();
069: private BorderLayout borderLayout1 = new BorderLayout();
070: private FileTreeSelector fileSelector = null;
071: private JPanel controlPanel = new JPanel();
072: private JPanel fileNamePanel = new JPanel();
073: private JLabel fileNameLabel = new JLabel();
074: private JTextField fileNameField = new JTextField("");
075: private JPanel buttonPanel = new JPanel();
076: private JButton approveButton = new JButton(res
077: .getString("button.select.dir"));
078: private JButton cancelButton = new JButton(res
079: .getString("button.cancel"));
080: private JRootPane owner;
081:
082: private int returnValue = JFileChooser.CANCEL_OPTION;
083: private TreePath defaultDirectoryPath = null;
084:
085: public CustomDirectoryChooser(JRootPane owner, File defaultFile,
086: boolean showHiddenFiles) throws HeadlessException {
087: this .owner = owner;
088: setModal(true);
089: String desiredName = defaultFile.getName();
090: try {
091: fileSelector = new FileTreeSelector(FileSystemModel
092: .factory(desiredName, showHiddenFiles), false);
093: defaultDirectoryPath = fileSelector
094: .setDefaultDirectory(defaultFile);
095: fileNameField.setText(fileSelector.getDefaultDirectory()
096: .getAbsolutePath());
097: jbInit();
098: setLocationRelativeTo(owner);
099: } catch (Exception e) {
100: e.printStackTrace();
101: }
102: }
103:
104: public void setFileHidingEnabled(boolean fileHiding) {
105: try {
106: DefaultTreeModel treeModel = (DefaultTreeModel) fileSelector
107: .getModel().getRoot();
108: DirectoryMutableTreeNode top = (DirectoryMutableTreeNode) treeModel
109: .getRoot();
110: FileSystemModel fsm = (FileSystemModel) top.getUserObject();
111: fsm.setShowHidden(!fileHiding);
112: } catch (ClassCastException e) {
113: // ItemModel does not support hiding
114: }
115: }
116:
117: public int showDialog(Component parent, String approveButtonText) {
118: setLocationRelativeTo(owner);
119: tryScrolltoView();
120: show();
121: return returnValue;
122: }
123:
124: public void setDefaultDirectory(File dirPath) {
125: defaultDirectoryPath = fileSelector
126: .setDefaultDirectory(dirPath);
127: fileNameField.setText(fileSelector.getDefaultDirectory()
128: .getAbsolutePath());
129: }
130:
131: public File getSelectedFile() {
132: File selected = fileSelector.getSelectedFile();
133: File field = new File(fileNameField.getText());
134: if (selected == null) {
135: return field;
136: } else if (!selected.equals(field)) {
137: return field; // hand written text has precedence
138: }
139: return selected;
140: }
141:
142: public JTree getJTree() {
143: return fileSelector;
144: }
145:
146: private void jbInit() throws Exception {
147: this .getContentPane().setLayout(borderLayout1);
148: this .getContentPane().add(jScrollPane1, BorderLayout.CENTER);
149: jScrollPane1.getViewport().setView(fileSelector);
150:
151: // layout components
152: jScrollPane1.setBorder(BorderFactory.createCompoundBorder(
153: BorderFactory.createEmptyBorder(10, 10, 5, 10),
154: BorderFactory.createCompoundBorder(BorderFactory
155: .createLineBorder(controlPanel.getBackground()
156: .darker(), 1), BorderFactory
157: .createEmptyBorder(2, 1, 1, 1))));
158: fileSelector.setBorder(BorderFactory.createEmptyBorder(5, 5, 5,
159: 5));
160: controlPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5,
161: 5));
162: fileNamePanel.setBorder(BorderFactory.createEmptyBorder(0, 5,
163: 5, 5));
164: controlPanel.setLayout(new BorderLayout());
165: fileNamePanel.setLayout(new BorderLayout());
166: buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
167:
168: // connect UI components
169: buttonPanel.add(approveButton);
170: buttonPanel.add(cancelButton);
171:
172: fileNamePanel.add(fileNameLabel, BorderLayout.EAST);
173: fileNamePanel.add(fileNameField, BorderLayout.CENTER);
174:
175: controlPanel.add(fileNamePanel, BorderLayout.NORTH);
176: controlPanel.add(buttonPanel, BorderLayout.SOUTH);
177: this .getContentPane().add(controlPanel, BorderLayout.SOUTH);
178: this .pack();
179: this .setSize(450, 300);
180: setLocationRelativeTo(getOwner());
181: //this.setLocation(.getLocationOnScreen());
182:
183: addWindowListener(new WindowAdapter() {
184: public void windowClosing(WindowEvent e) {
185: returnValue = JFileChooser.CANCEL_OPTION;
186: }
187: });
188: approveButton.addActionListener(new ActionListener() {
189: public void actionPerformed(ActionEvent e) {
190: CustomDirectoryChooser.this .returnValue = JFileChooser.APPROVE_OPTION;
191: CustomDirectoryChooser.this .hide();
192: }
193: });
194: cancelButton.addActionListener(new ActionListener() {
195: public void actionPerformed(ActionEvent e) {
196: CustomDirectoryChooser.this .returnValue = JFileChooser.CANCEL_OPTION;
197: CustomDirectoryChooser.this .hide();
198: }
199: });
200:
201: // TODO make double clicking directories work
202: fileSelector.addFileActionListener(new FileActionListener() {
203: public void actionPerformed(ActionEvent e) {
204: CustomDirectoryChooser.this .returnValue = JFileChooser.APPROVE_OPTION;
205: CustomDirectoryChooser.this .hide();
206: }
207: });
208: fileSelector
209: .addTreeSelectionListener(new TreeSelectionListener() {
210: public void valueChanged(TreeSelectionEvent e) {
211: TreePath path = e.getNewLeadSelectionPath();
212: if (path != null) {
213: DirectoryMutableTreeNode dmtn = (DirectoryMutableTreeNode) path
214: .getLastPathComponent();
215: ItemModel m = (ItemModel) dmtn
216: .getUserObject();
217: fileNameField.setText(m.getFullPath());
218: }
219: }
220: });
221: }
222:
223: public TreePath getDefaultDirectoryPath() {
224: return defaultDirectoryPath;
225: }
226:
227: private void tryScrolltoView() {
228: SwingUtilities.invokeLater(new Runnable() {
229: public void run() {
230: try {
231: Thread.sleep(500);
232: } catch (InterruptedException e) {
233: }
234: getJTree().scrollPathToVisible(defaultDirectoryPath);
235: }
236: });
237: }
238:
239: }
|