View Javadoc

1   package net.sourceforge.jpotpourri.gui.chooser;
2   
3   import java.awt.GridBagConstraints;
4   import java.awt.GridBagLayout;
5   import java.awt.Insets;
6   import java.awt.event.ActionEvent;
7   import java.awt.event.ActionListener;
8   import java.io.File;
9   import java.util.HashSet;
10  import java.util.Set;
11  
12  import javax.swing.JButton;
13  import javax.swing.JFileChooser;
14  import javax.swing.JOptionPane;
15  import javax.swing.JPanel;
16  import javax.swing.JTextField;
17  import javax.swing.filechooser.FileFilter;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  
22  /**
23   * 
24   * @author christoph_pickl@users.sourceforge.net
25   */
26  abstract class AbstractFileDirectoryChooser extends JPanel implements ActionListener {
27  
28  	private static final long serialVersionUID = 6190683599071858829L;
29  
30  	private static final Log LOG = LogFactory.getLog(AbstractFileDirectoryChooser.class);
31  
32      private static final int DIRECTORY_PATH_FIELD_SIZE = 15;
33      
34      static final String DEFAULT_BUTTON_LABEL = "Set";
35      
36      static final ButtonPosition DEFAULT_BUTTON_POSITION = ButtonPosition.RIGHT;
37      
38      
39      private File fileOrDir;
40      
41      private JTextField directoryPath = new JTextField(DIRECTORY_PATH_FIELD_SIZE);
42  
43      /** Can be null. */
44      private File defaultPath;
45  
46      private final String dialogTitle;
47      
48      private final JButton button;
49  
50      private final Set<IFileDirectoryChooserListener> listeners = new HashSet<IFileDirectoryChooserListener>();
51      
52      
53      
54      public AbstractFileDirectoryChooser(final String dialogTitle) {
55          this(dialogTitle, null, DEFAULT_BUTTON_POSITION, DEFAULT_BUTTON_LABEL);
56      }
57  
58      public AbstractFileDirectoryChooser(final String dialogTitle, final ButtonPosition position) {
59          this(dialogTitle, null, position, DEFAULT_BUTTON_LABEL);
60      }
61  
62      public AbstractFileDirectoryChooser(final String dialogTitle, final File defaultPath,
63      		final ButtonPosition position) {
64          this(dialogTitle, defaultPath, position, DEFAULT_BUTTON_LABEL);
65      }
66      
67      public AbstractFileDirectoryChooser(final String dialogTitle, final File defaultPath,
68      		final ButtonPosition position, final String buttonLabel) {
69          LOG.info("Constructing new directory chooser instance (buttonLabel=" + buttonLabel + "; "
70          		+ "defaultPath=" + (defaultPath == null ? "null" : defaultPath.getAbsolutePath()) + ").");
71          assert (buttonLabel.length() > 0);
72          
73          this.defaultPath = defaultPath;
74          this.directoryPath.setEditable(false);
75          this.dialogTitle = dialogTitle;
76          
77          this.button = new JButton(buttonLabel);
78          this.button.setOpaque(false);
79          this.button.addActionListener(this);
80          
81          this.initComponents(position);
82      }
83      
84      
85      
86      private void initComponents(final ButtonPosition btnPosition) {
87          this.setOpaque(false);
88          final GridBagLayout layout = new GridBagLayout();
89          final GridBagConstraints c = new GridBagConstraints();
90          layout.setConstraints(this, c);
91          this.setLayout(layout);
92  
93          c.anchor = GridBagConstraints.FIRST_LINE_START;
94          c.gridy = 0;
95  
96          final int buttonTextGap = 6;
97  
98          c.fill = (btnPosition == ButtonPosition.LEFT) ? GridBagConstraints.NONE : GridBagConstraints.HORIZONTAL;        
99          c.insets = new Insets(0, 0, 0, (btnPosition == ButtonPosition.LEFT) ? buttonTextGap : 0); // adjust right margin
100         c.gridx = 0;
101         this.add((btnPosition == ButtonPosition.LEFT) ? this.button : this.directoryPath, c);
102 
103         c.fill = (btnPosition == ButtonPosition.LEFT) ? GridBagConstraints.HORIZONTAL : GridBagConstraints.NONE;
104         c.insets = new Insets(0, (btnPosition == ButtonPosition.LEFT) ? 0 : buttonTextGap, 0, 0); // adjust left margin
105         c.gridx++;
106         this.add((btnPosition == ButtonPosition.LEFT) ? this.directoryPath : this.button, c);
107         
108     }
109     
110     final void setFileOrDir(final File fileOrDir) {
111         this.fileOrDir = fileOrDir;
112         
113         if (this.fileOrDir == null) {
114             this.clearYourself();
115         } else {
116             if (this.fileOrDir.exists() && this.isRightFileOrDir(fileOrDir)) {
117             	this.directoryPath.setText(this.fileOrDir.getAbsolutePath());
118             } else {
119             	final String errorMessage = this.fileOrDir.exists() == false
120             			? "Given " + this.getFileDirName() + " '" + fileOrDir.getAbsolutePath() + "'  does not exist!"
121             			: "The " + this.getFileDirName() + " '" + fileOrDir.getAbsolutePath() + "' is invalid!";
122             	JOptionPane.showMessageDialog(this, errorMessage, "Invalid File", JOptionPane.WARNING_MESSAGE);
123                 this.clearYourself();
124             }
125         }
126     }
127 
128     public final void uncheckedSetFileOrDir(final File directory) {
129         this.fileOrDir = directory;
130         this.directoryPath.setText(this.fileOrDir.getAbsolutePath());
131     }
132     
133     // for future use: could clear folder-icon
134     private void clearYourself() {
135         this.directoryPath.setText("");
136     }
137     
138     /**
139      * @return can be null
140      */
141     final File getFileOrDir() {
142         return this.fileOrDir;
143     }
144     
145     abstract boolean isRightFileOrDir(final File file);
146     
147     /**
148      * @return the string "File" or "Directory"
149      */
150     abstract String getFileDirName();
151     
152     public final void setDefaultPath(final File defaultPath) {
153     	LOG.debug("Setting default path to '" + (defaultPath == null ? "null" : defaultPath.getAbsolutePath()) + "'.");
154         this.defaultPath = defaultPath;
155     }
156 
157     abstract int getSelectionMode();
158     abstract FileFilter getFileFilter();
159     
160     public final void actionPerformed(final ActionEvent event) {
161     	assert(event.getSource() == this.button);
162         LOG.debug("showing file chooser with default path '"
163         		+ (this.defaultPath == null ? "null" : this.defaultPath.getAbsolutePath()) + "'...");
164         
165         final JFileChooser chooser = new JFileChooser(this.defaultPath);
166         chooser.setDialogTitle(this.dialogTitle);
167         chooser.setMultiSelectionEnabled(false);
168         chooser.setFileSelectionMode(getSelectionMode());
169         
170         if (getFileFilter() != null) {
171             chooser.setFileFilter(getFileFilter());
172         }
173         
174         int returnVal = chooser.showOpenDialog(AbstractFileDirectoryChooser.this);
175         if (returnVal == JFileChooser.APPROVE_OPTION) {
176             final File selectedFileOrDir = chooser.getSelectedFile();
177             assert (selectedFileOrDir != null);
178             setFileOrDir(selectedFileOrDir);
179             
180             for (final IFileDirectoryChooserListener listener : this.listeners) {
181                 listener.doChoosen(selectedFileOrDir);
182             }
183         } else {
184             LOG.debug("User canceled action.");
185         }
186     }
187     
188     
189     public final void addChooserListener(final IFileDirectoryChooserListener listener) {
190         this.listeners.add(listener);
191     }
192     public final void removeDirectoryChooserListener(final IFileDirectoryChooserListener listener) {
193         this.listeners.remove(listener);
194     }
195     
196     @Override
197     public final void setEnabled(final boolean enabled) {
198         this.button.setEnabled(enabled);
199     }
200 
201     
202 }