001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032: package com.vividsolutions.jump.workbench.datasource;
033:
034: import java.awt.*;
035: import java.awt.event.ActionEvent;
036: import java.awt.event.ActionListener;
037: import java.io.File;
038: import java.util.*;
039:
040: import javax.swing.*;
041: import javax.swing.filechooser.FileFilter;
042: import javax.swing.plaf.basic.BasicFileChooserUI;
043:
044: import com.vividsolutions.jump.I18N;
045: import com.vividsolutions.jump.coordsys.CoordinateSystem;
046: import com.vividsolutions.jump.coordsys.CoordinateSystemRegistry;
047: import com.vividsolutions.jump.io.datasource.DataSource;
048: import com.vividsolutions.jump.io.datasource.DataSourceQuery;
049: import com.vividsolutions.jump.util.Blackboard;
050: import com.vividsolutions.jump.util.LangUtil;
051: import com.vividsolutions.jump.workbench.ui.GUIUtil;
052: import com.vividsolutions.jump.util.CollectionUtil;
053:
054: /**
055: * UI for picking datasets stored in files. Generates two properties: the filename
056: * and the CoordinateSystem.
057: * @see com.vividsolutions.jump.coordsys.CoordinateSystem
058: */
059: public abstract class FileDataSourceQueryChooser implements
060: DataSourceQueryChooser {
061: private String description;
062: private Class dataSourceClass;
063: private FileFilter fileFilter;
064: private JPanel southComponent1 = new JPanel();
065: private JPanel southComponent2 = new JPanel();
066: private String[] extensions;
067:
068: /**
069: * @param extensions e.g. txt
070: */
071: public FileDataSourceQueryChooser(Class dataSourceClass,
072: String description, String[] extensions) {
073: this .dataSourceClass = dataSourceClass;
074: this .description = description;
075: this .extensions = extensions;
076: fileFilter = GUIUtil.createFileFilter(description, extensions);
077: }
078:
079: public String toString() {
080: return description;
081: }
082:
083: public boolean isInputValid() {
084: //Trick to allow inner class to modify an outside variable:
085: //stick the variable in an array. [Jon Aquino]
086: final Boolean[] actionPerformed = new Boolean[] { Boolean.FALSE };
087: ActionListener listener = new ActionListener() {
088: public void actionPerformed(ActionEvent e) {
089: actionPerformed[0] = Boolean.TRUE;
090: }
091: };
092:
093: getFileChooserPanel().getChooser().addActionListener(listener);
094:
095: try {
096: //Workaround for Java Bug 4528663 "JFileChooser doesn't return what is
097: //typed in the file name text field." [Jon Aquino]
098: if (getFileChooserPanel().getChooser().getUI() instanceof BasicFileChooserUI) {
099: BasicFileChooserUI ui = (BasicFileChooserUI) getFileChooserPanel()
100: .getChooser().getUI();
101: ui.getApproveSelectionAction().actionPerformed(null);
102: }
103: } finally {
104: getFileChooserPanel().getChooser().removeActionListener(
105: listener);
106: }
107:
108: return actionPerformed[0] == Boolean.TRUE;
109: }
110:
111: public Collection getDataSourceQueries() {
112: ArrayList queries = new ArrayList();
113: File[] files = GUIUtil.selectedFiles(getFileChooserPanel()
114: .getChooser());
115:
116: for (int i = 0; i < files.length; i++) {
117: //LDB: mod to append standard extension to save file names
118: String fname = files[i].getAbsolutePath();
119: if (fname.lastIndexOf(".") == -1) {
120: fname = fname + "." + extensions[0]; //first extension (i.e. shp)
121: }
122: File file = new File(fname);
123: queries.addAll(toDataSourceQueries(file));
124: //queries.addAll(toDataSourceQueries(files[i]));
125: }
126:
127: return queries;
128: }
129:
130: //Overridden by IGDSDataSourceQueryChooser [Jon Aquino]
131: protected Collection toDataSourceQueries(File file) {
132: return Collections.singleton(toDataSourceQuery(file));
133: }
134:
135: protected abstract FileChooserPanel getFileChooserPanel();
136:
137: public Component getComponent() {
138: setFileFilters();
139:
140: if (getFileChooserPanel().getSouthComponent1() != getSouthComponent1()) {
141: getFileChooserPanel().setSouthComponent1(
142: getSouthComponent1());
143: }
144:
145: if (getFileChooserPanel().getSouthComponent2() != getSouthComponent2()) {
146: getFileChooserPanel().setSouthComponent2(
147: getSouthComponent2());
148: }
149:
150: getFileChooserPanel().revalidate();
151: getFileChooserPanel().repaint();
152:
153: return getFileChooserPanel();
154: }
155:
156: //
157: // It's confusing having two comboboxes having formats (the one at the
158: // top and the one at the bottom). To help things a bit, simplify the lower one
159: // to always display *.*. [Jon Aquino]
160: //
161: // JJ - eziLink users (and myself) found themselves clicking on a shapefile,
162: // only to be told that the file couldn't be read becuase the menu at the
163: // top of the dialog was set to a different format. It was also difficult
164: // to pick out the shapefiles, because there are so many other files associated
165: // with each shapefile. So we've re-enabled the file filters.
166: //
167: private void setFileFilters() {
168: //
169: // Only set the file filter if we have to, because refreshing the view
170: // takes time. [Jon Aquino]
171: //
172: FileFilter[] filters = getFileChooserPanel().getChooser()
173: .getChoosableFileFilters();
174: if (!CollectionUtil.containsReference(filters, getFileFilter())) {
175: GUIUtil.removeChoosableFileFilters(getFileChooserPanel()
176: .getChooser());
177: addFileFilters(getFileChooserPanel().getChooser());
178: getFileChooserPanel().getChooser().setFileFilter(
179: getFileFilter());
180: }
181: }
182:
183: protected void addFileFilters(JFileChooser chooser) {
184: chooser.addChoosableFileFilter(getFileFilter());
185: chooser
186: .addChoosableFileFilter(chooser
187: .getAcceptAllFileFilter());
188: }
189:
190: public DataSourceQuery toDataSourceQuery(File file) {
191: DataSource dataSource = (DataSource) LangUtil
192: .newInstance(dataSourceClass);
193: dataSource.setProperties(toProperties(file));
194:
195: return new DataSourceQuery(dataSource, null, GUIUtil
196: .nameWithoutExtension(file));
197: }
198:
199: protected Map toProperties(File file) {
200: HashMap properties = new HashMap();
201: properties.put(DataSource.FILE_KEY, file.getPath());
202: properties.put(DataSource.COORDINATE_SYSTEM_KEY,
203: getFileChooserPanel().getSelectedCoordinateSystem()
204: .getName());
205:
206: return properties;
207: }
208:
209: public static void main(String[] args) {
210: JFileChooser chooser = new JFileChooser();
211: JFrame f = new JFrame();
212: f.getContentPane().add(chooser);
213: f.pack();
214: f.setVisible(true);
215: }
216:
217: public FileFilter getFileFilter() {
218: return fileFilter;
219: }
220:
221: protected Component getSouthComponent1() {
222: return southComponent1;
223: }
224:
225: protected Component getSouthComponent2() {
226: return southComponent2;
227: }
228:
229: protected static class FileChooserPanel extends JPanel {
230: private JFileChooser chooser;
231: private Component southComponent1;
232: private Component southComponent2;
233: private JComboBox coordinateSystemComboBox = new JComboBox();
234: private JLabel coordinateSystemLabel = new JLabel(
235: I18N
236: .get("datasource.FileDataSourceQueryChooser.coordinate-system-of-file")
237: + " ") {
238:
239: {
240: setDisplayedMnemonic('r');
241: setLabelFor(coordinateSystemComboBox);
242: }
243: };
244:
245: private JPanel southComponent1Container = new JPanel(
246: new BorderLayout());
247: private JPanel southComponent2Container = new JPanel(
248: new BorderLayout());
249:
250: public FileChooserPanel(JFileChooser chooser,
251: Blackboard blackboard) {
252: setLayout(new BorderLayout());
253: ArrayList sortedSystems = new ArrayList(
254: CoordinateSystemRegistry.instance(blackboard)
255: .getCoordinateSystems());
256: Collections.sort(sortedSystems);
257: coordinateSystemComboBox.setModel(new DefaultComboBoxModel(
258: new Vector(sortedSystems)));
259: this .chooser = chooser;
260:
261: JPanel southPanel = new JPanel(new GridBagLayout());
262: southPanel.add(coordinateSystemLabel,
263: new GridBagConstraints(0, 0, 1, 1, 0, 0,
264: GridBagConstraints.WEST,
265: GridBagConstraints.NONE, new Insets(0, 0,
266: 0, 0), 0, 0));
267: southPanel.add(coordinateSystemComboBox,
268: new GridBagConstraints(1, 0, 1, 1, 0, 0,
269: GridBagConstraints.WEST,
270: GridBagConstraints.NONE, new Insets(0, 0,
271: 0, 0), 0, 0));
272: southPanel.add(southComponent1Container,
273: new GridBagConstraints(2, 0, 1, 1, 1, 0,
274: GridBagConstraints.WEST,
275: GridBagConstraints.HORIZONTAL, new Insets(
276: 0, 4, 0, 0), 0, 0));
277: southPanel.add(southComponent2Container,
278: new GridBagConstraints(0, 1, 3, 1, 1, 0,
279: GridBagConstraints.WEST,
280: GridBagConstraints.HORIZONTAL, new Insets(
281: 0, 0, 0, 0), 0, 0));
282: add(chooser, BorderLayout.CENTER);
283: add(southPanel, BorderLayout.SOUTH);
284: coordinateSystemComboBox.setVisible(false);
285: coordinateSystemLabel.setVisible(false);
286: setSouthComponent1(new JPanel());
287: setSouthComponent2(new JPanel());
288: }
289:
290: private void setSouthComponent1(Component southComponent1) {
291: southComponent1Container.removeAll();
292: this .southComponent1 = southComponent1;
293: southComponent1Container.add(southComponent1,
294: BorderLayout.CENTER);
295: }
296:
297: private void setSouthComponent2(Component southComponent2) {
298: southComponent2Container.removeAll();
299: this .southComponent2 = southComponent2;
300: southComponent2Container.add(southComponent2,
301: BorderLayout.CENTER);
302: }
303:
304: public JFileChooser getChooser() {
305: return chooser;
306: }
307:
308: private Component getSouthComponent1() {
309: return southComponent1;
310: }
311:
312: private Component getSouthComponent2() {
313: return southComponent2;
314: }
315:
316: public void setCoordinateSystemComboBoxVisible(boolean visible) {
317: coordinateSystemComboBox.setVisible(visible);
318: coordinateSystemLabel.setVisible(visible);
319: }
320:
321: public CoordinateSystem getSelectedCoordinateSystem() {
322: return coordinateSystemComboBox.isVisible() ? (CoordinateSystem) coordinateSystemComboBox
323: .getSelectedItem()
324: : CoordinateSystem.UNSPECIFIED;
325: }
326:
327: public void setSelectedCoordinateSystem(String name) {
328: coordinateSystemComboBox
329: .setSelectedItem(coordinateSystem(name));
330: }
331:
332: private CoordinateSystem coordinateSystem(String name) {
333: for (int i = 0; i < coordinateSystemComboBox.getItemCount(); i++) {
334: if (((CoordinateSystem) coordinateSystemComboBox
335: .getItemAt(i)).getName().equals(name)) {
336: return (CoordinateSystem) coordinateSystemComboBox
337: .getItemAt(i);
338: }
339: }
340: return null;
341: }
342: }
343:
344: public String[] getExtensions() {
345: return extensions;
346: }
347: }
|