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
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
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);
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);
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
134 private void clearYourself() {
135 this.directoryPath.setText("");
136 }
137
138
139
140
141 final File getFileOrDir() {
142 return this.fileOrDir;
143 }
144
145 abstract boolean isRightFileOrDir(final File file);
146
147
148
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 }