/* * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI * for visualizing and manipulating spatial features with geometry and attributes. * * Copyright (C) 2003 Vivid Solutions * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * For more information, contact: * * Vivid Solutions * Suite #1A * 2328 Government Street * Victoria BC V8T 5G5 * Canada * * (250)385-6040 * www.vividsolutions.com */ package com.vividsolutions.jump.workbench.datasource; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.*; import javax.swing.*; import javax.swing.filechooser.FileFilter; import javax.swing.plaf.basic.BasicFileChooserUI; import com.vividsolutions.jump.I18N; import com.vividsolutions.jump.coordsys.CoordinateSystem; import com.vividsolutions.jump.coordsys.CoordinateSystemRegistry; import com.vividsolutions.jump.io.datasource.DataSource; import com.vividsolutions.jump.io.datasource.DataSourceQuery; import com.vividsolutions.jump.util.Blackboard; import com.vividsolutions.jump.util.LangUtil; import com.vividsolutions.jump.workbench.ui.GUIUtil; import com.vividsolutions.jump.util.CollectionUtil; /** * UI for picking datasets stored in files. Generates two properties: the filename * and the CoordinateSystem. * @see com.vividsolutions.jump.coordsys.CoordinateSystem */ public abstract class FileDataSourceQueryChooser implements DataSourceQueryChooser { private String description; private Class dataSourceClass; private FileFilter fileFilter; private JPanel southComponent1 = new JPanel(); private JPanel southComponent2 = new JPanel(); private String[] extensions; /** * @param extensions e.g. txt */ public FileDataSourceQueryChooser(Class dataSourceClass, String description, String[] extensions) { this.dataSourceClass = dataSourceClass; this.description = description; this.extensions = extensions; fileFilter = GUIUtil.createFileFilter(description, extensions); } public String toString() { return description; } public boolean isInputValid() { //Trick to allow inner class to modify an outside variable: //stick the variable in an array. [Jon Aquino] final Boolean[] actionPerformed = new Boolean[] { Boolean.FALSE }; ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { actionPerformed[0] = Boolean.TRUE; } }; getFileChooserPanel().getChooser().addActionListener(listener); try { //Workaround for Java Bug 4528663 "JFileChooser doesn't return what is //typed in the file name text field." [Jon Aquino] if (getFileChooserPanel().getChooser().getUI() instanceof BasicFileChooserUI) { BasicFileChooserUI ui = (BasicFileChooserUI) getFileChooserPanel() .getChooser() .getUI(); ui.getApproveSelectionAction().actionPerformed(null); } } finally { getFileChooserPanel().getChooser().removeActionListener(listener); } return actionPerformed[0] == Boolean.TRUE; } public Collection getDataSourceQueries() { ArrayList queries = new ArrayList(); File[] files = GUIUtil.selectedFiles(getFileChooserPanel().getChooser()); for (int i = 0; i < files.length; i++) { //LDB: mod to append standard extension to save file names String fname = files[i].getAbsolutePath(); if (fname.lastIndexOf(".") == -1) { fname = fname + "." + extensions[0]; //first extension (i.e. shp) } File file = new File(fname); queries.addAll(toDataSourceQueries(file)); //queries.addAll(toDataSourceQueries(files[i])); } return queries; } //Overridden by IGDSDataSourceQueryChooser [Jon Aquino] protected Collection toDataSourceQueries(File file) { return Collections.singleton(toDataSourceQuery(file)); } protected abstract FileChooserPanel getFileChooserPanel(); public Component getComponent() { setFileFilters(); if (getFileChooserPanel().getSouthComponent1() != getSouthComponent1()) { getFileChooserPanel().setSouthComponent1(getSouthComponent1()); } if (getFileChooserPanel().getSouthComponent2() != getSouthComponent2()) { getFileChooserPanel().setSouthComponent2(getSouthComponent2()); } getFileChooserPanel().revalidate(); getFileChooserPanel().repaint(); return getFileChooserPanel(); } // // It's confusing having two comboboxes having formats (the one at the // top and the one at the bottom). To help things a bit, simplify the lower one // to always display *.*. [Jon Aquino] // // JJ - eziLink users (and myself) found themselves clicking on a shapefile, // only to be told that the file couldn't be read becuase the menu at the // top of the dialog was set to a different format. It was also difficult // to pick out the shapefiles, because there are so many other files associated // with each shapefile. So we've re-enabled the file filters. // private void setFileFilters() { // // Only set the file filter if we have to, because refreshing the view // takes time. [Jon Aquino] // FileFilter[] filters = getFileChooserPanel().getChooser().getChoosableFileFilters(); if ( ! CollectionUtil.containsReference( filters, getFileFilter() ) ) { GUIUtil.removeChoosableFileFilters(getFileChooserPanel().getChooser()); addFileFilters(getFileChooserPanel().getChooser()); getFileChooserPanel().getChooser().setFileFilter(getFileFilter()); } } protected void addFileFilters(JFileChooser chooser) { chooser.addChoosableFileFilter(getFileFilter()); chooser.addChoosableFileFilter(chooser.getAcceptAllFileFilter()); } public DataSourceQuery toDataSourceQuery(File file) { DataSource dataSource = (DataSource) LangUtil.newInstance(dataSourceClass); dataSource.setProperties(toProperties(file)); return new DataSourceQuery(dataSource, null, GUIUtil.nameWithoutExtension(file)); } protected Map toProperties(File file) { HashMap properties = new HashMap(); properties.put(DataSource.FILE_KEY, file.getPath()); properties.put(DataSource.COORDINATE_SYSTEM_KEY, getFileChooserPanel().getSelectedCoordinateSystem().getName()); return properties; } public static void main(String[] args) { JFileChooser chooser = new JFileChooser(); JFrame f = new JFrame(); f.getContentPane().add(chooser); f.pack(); f.setVisible(true); } public FileFilter getFileFilter() { return fileFilter; } protected Component getSouthComponent1() { return southComponent1; } protected Component getSouthComponent2() { return southComponent2; } protected static class FileChooserPanel extends JPanel { private JFileChooser chooser; private Component southComponent1; private Component southComponent2; private JComboBox coordinateSystemComboBox = new JComboBox(); private JLabel coordinateSystemLabel = new JLabel(I18N.get("datasource.FileDataSourceQueryChooser.coordinate-system-of-file")+" ") { { setDisplayedMnemonic('r'); setLabelFor(coordinateSystemComboBox); } }; private JPanel southComponent1Container = new JPanel(new BorderLayout()); private JPanel southComponent2Container = new JPanel(new BorderLayout()); public FileChooserPanel(JFileChooser chooser, Blackboard blackboard) { setLayout(new BorderLayout()); ArrayList sortedSystems = new ArrayList( CoordinateSystemRegistry.instance(blackboard).getCoordinateSystems() ); Collections.sort( sortedSystems ); coordinateSystemComboBox.setModel(new DefaultComboBoxModel( new Vector(sortedSystems) ) ); this.chooser = chooser; JPanel southPanel = new JPanel(new GridBagLayout()); southPanel.add(coordinateSystemLabel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); southPanel.add(coordinateSystemComboBox, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); southPanel.add(southComponent1Container, new GridBagConstraints(2, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 4, 0, 0), 0, 0)); southPanel.add(southComponent2Container, new GridBagConstraints(0, 1, 3, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); add(chooser, BorderLayout.CENTER); add(southPanel, BorderLayout.SOUTH); coordinateSystemComboBox.setVisible(false); coordinateSystemLabel.setVisible(false); setSouthComponent1(new JPanel()); setSouthComponent2(new JPanel()); } private void setSouthComponent1(Component southComponent1) { southComponent1Container.removeAll(); this.southComponent1 = southComponent1; southComponent1Container.add(southComponent1, BorderLayout.CENTER); } private void setSouthComponent2(Component southComponent2) { southComponent2Container.removeAll(); this.southComponent2 = southComponent2; southComponent2Container.add(southComponent2, BorderLayout.CENTER); } public JFileChooser getChooser() { return chooser; } private Component getSouthComponent1() { return southComponent1; } private Component getSouthComponent2() { return southComponent2; } public void setCoordinateSystemComboBoxVisible(boolean visible) { coordinateSystemComboBox.setVisible(visible); coordinateSystemLabel.setVisible(visible); } public CoordinateSystem getSelectedCoordinateSystem() { return coordinateSystemComboBox.isVisible() ? (CoordinateSystem) coordinateSystemComboBox.getSelectedItem() : CoordinateSystem.UNSPECIFIED; } public void setSelectedCoordinateSystem(String name) { coordinateSystemComboBox.setSelectedItem(coordinateSystem(name)); } private CoordinateSystem coordinateSystem(String name) { for (int i = 0; i < coordinateSystemComboBox.getItemCount(); i++) { if (((CoordinateSystem)coordinateSystemComboBox.getItemAt(i)).getName().equals(name)) { return (CoordinateSystem)coordinateSystemComboBox.getItemAt(i); } } return null; } } public String[] getExtensions() { return extensions; } public String getDescription() { return description; } public Class getDataSourceClass() { return dataSourceClass; } }