001/*
002 * $Id: SoundingFileBrowser.java,v 1.7 2011/03/24 16:06:31 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2011
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 * 
012 * All Rights Reserved
013 * 
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.  
016 * 
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 * 
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025 * GNU Lesser Public License for more details.
026 * 
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program.  If not, see http://www.gnu.org/licenses.
029 */
030
031package edu.wisc.ssec.mcidasv.chooser;
032
033
034import ucar.unidata.beans.NonVetoableProperty;
035import ucar.unidata.beans.Property;
036import ucar.unidata.beans.PropertySet;
037import ucar.unidata.data.sounding.CMASoundingAdapter;
038import ucar.unidata.data.sounding.NetcdfSoundingAdapter;
039import ucar.unidata.data.sounding.SoundingAdapter;
040
041
042import ucar.unidata.util.FileManager;
043
044import ucar.unidata.util.GuiUtils;
045import ucar.unidata.util.LogUtil;
046import ucar.unidata.util.Misc;
047import ucar.unidata.util.PatternFileFilter;
048
049
050
051import java.awt.Component;
052import java.awt.Insets;
053import java.awt.event.ActionEvent;
054import java.awt.event.ActionListener;
055import java.awt.event.WindowAdapter;
056import java.awt.event.WindowEvent;
057import java.awt.event.WindowListener;
058
059import java.beans.*;
060
061import java.io.File;
062
063import javax.swing.BorderFactory;
064import javax.swing.JButton;
065import javax.swing.JFrame;
066import javax.swing.JOptionPane;
067import javax.swing.JPanel;
068import javax.swing.JTextField;
069
070
071/**
072 * A browser for finding netCDF upper air files.
073 *
074 * @author Unidata development team
075 * @version $Revision: 1.7 $
076 */
077public class SoundingFileBrowser {
078
079    /** PatternFileFilter for upper air netCDF files */
080    public static final PatternFileFilter FILTER_NC =
081        new PatternFileFilter(".*ua\\.nc$,Upperair.*\\.nc$",
082                              "netCDF Upper Air files (*ua.nc)");
083
084    /** PatternFileFilter for CMA upper air files */
085    public static final PatternFileFilter FILTER_CMA_UA =
086        new PatternFileFilter(".*\\.ta$", "CMA Upper Air files (*.ta)");
087
088    /** property for the sounding adapter */
089    private Property soundingAdapterProperty;
090
091    /** property set */
092    private PropertySet propertySet;
093
094    /** selected file input */
095    protected JTextField selectedFileDisplay;
096
097    /** flag for file changes */
098    private boolean ignoreChangingFile = false;
099
100    /** frame for the browse */
101    private static JFrame frame = null;
102
103    /** frame contents */
104    private JPanel contents;
105
106    /**
107     * Construct an object for selecting sounding files starting at
108     * the current directory
109     */
110    SoundingFileBrowser() {
111        this(".");
112    }
113
114    /**
115     * Construct an object for selecting sounding files starting at
116     * the specified directory.
117     *
118     * @param  directoryName   starting directory to search for files.
119     */
120    SoundingFileBrowser(String directoryName) {
121
122        // set up the properties
123        propertySet = new PropertySet();
124
125        propertySet.addProperty(soundingAdapterProperty =
126            new NonVetoableProperty(this, "soundingAdapter"));
127
128        File selectedFile = new File(directoryName);
129
130
131        selectedFileDisplay = new JTextField(30);
132        selectedFileDisplay.addActionListener(new ActionListener() {
133            public void actionPerformed(ActionEvent ae) {
134                checkNewFile(new File(selectedFileDisplay.getText().trim()));
135            }
136        });
137        GuiUtils.setNoFill();
138        GuiUtils.tmpInsets = new Insets(0, 2, 0, 2);
139        contents = GuiUtils.doLayout(new Component[] { selectedFileDisplay,
140                fileSelectionButton() }, 2, GuiUtils.WT_N, GuiUtils.WT_N);
141    }
142
143
144    /**
145     * Create a file selection button
146     * @return the file selection button
147     */
148    private JButton fileSelectionButton() {
149        JButton fileSelectButton = new JButton("Select File...");
150        fileSelectButton.addActionListener(new ActionListener() {
151            public void actionPerformed(ActionEvent e) {
152                //Read the file - don't include the "include all" file filter.
153                String file =
154                    FileManager.getReadFile("Select Upper Air File",
155                                            Misc.newList(FILTER_NC,
156                                                FILTER_CMA_UA));
157                if (file == null) {
158                    return;
159                }
160                checkNewFile(new File(file));
161            }
162        });
163
164        return fileSelectButton;
165    }
166
167    /**
168     * Check the status of the file.
169     *
170     * @param selectedFile   file to use for checking
171     */
172    protected void checkNewFile(File selectedFile) {
173        if (ignoreChangingFile) {
174            return;
175        }
176        if ( !selectedFile.exists()) {
177            LogUtil.userMessage("File does not exist:" + selectedFile);
178            return;
179        }
180        SoundingAdapter adapter = null;
181        try {
182            adapter = new NetcdfSoundingAdapter(selectedFile);
183        } catch (IllegalArgumentException ill) {
184            System.out.println(ill.getMessage());
185            try {
186                adapter = new CMASoundingAdapter(selectedFile);
187            } catch (Exception exc) {
188                LogUtil.logException("Reading sounding:" + selectedFile, exc);
189                return;
190            }
191        } catch (Exception exc) {
192            LogUtil.logException("Reading sounding:" + selectedFile, exc);
193            return;
194        }
195        if (adapter.getSoundingTimes() != null) {
196            try {
197                soundingAdapterProperty.setValueAndNotifyListeners(adapter);
198                ignoreChangingFile = true;
199                selectedFileDisplay.setText(selectedFile.getPath());
200                ignoreChangingFile = false;
201            } catch (PropertyVetoException excpt) {
202                LogUtil.logException("New sounding dataset was vetoed: ",
203                                     excpt);
204            }
205        } else {
206            LogUtil.userMessage("Unable to read data from file "
207                                + selectedFile);
208        }
209    }
210
211
212    /**
213     * Get the contents of this browser.
214     *
215     * @return browser contents
216     */
217    public JPanel getContents() {
218        return contents;
219    }
220
221    /**
222     * Get the SoundingAdapter property
223     *
224     * @return the SoundingAdapter property
225     */
226    protected Property getSoundingAdapterProperty() {
227        return soundingAdapterProperty;
228    }
229
230    /**
231     * Get the SoundingAdapter associated with this browser
232     * @return the associated SoundingAdapter
233     */
234    public SoundingAdapter getSoundingAdapter() {
235        return (SoundingAdapter) soundingAdapterProperty.getValue();
236    }
237
238    /**
239     * Adds a property change listener.
240     *
241     * @param listener          The property change listener.
242     */
243    public void addPropertyChangeListener(PropertyChangeListener listener) {
244        propertySet.addPropertyChangeListener(listener);
245    }
246
247    /**
248     * Removes a property change listener.
249     *
250     * @param listener          The property change listener.
251     */
252    public void removePropertyChangeListener(
253            PropertyChangeListener listener) {
254        propertySet.removePropertyChangeListener(listener);
255    }
256
257    /**
258     * Adds a property change listener for a named property.
259     *
260     * @param name              The name of the property.
261     * @param listener          The property change listener.
262     */
263    public void addPropertyChangeListener(String name,
264                                          PropertyChangeListener listener) {
265        propertySet.addPropertyChangeListener(name, listener);
266    }
267
268    /**
269     * Removes a property change listener for a named property.
270     *
271     * @param name              The name of the property.
272     * @param listener          The property change listener.
273     */
274    public void removePropertyChangeListener(
275            String name, PropertyChangeListener listener) {
276        propertySet.removePropertyChangeListener(name, listener);
277    }
278
279    /**
280     * Test routine.
281     *
282     * @param args  name of file or directory if supplied
283     */
284    public static void main(String[] args) {
285
286        frame = new JFrame("Sounding Browser Test");
287
288        frame.addWindowListener(new WindowAdapter() {
289            public void windowClosing(WindowEvent e) {
290                System.exit(0);
291            }
292        });
293
294        SoundingFileBrowser ncfb = new SoundingFileBrowser((args.length > 0)
295                ? args[0]
296                : "/var/data/ldm/decoded");
297
298        frame.getContentPane().add(ncfb.getContents());
299        frame.pack();
300        frame.setVisible(true);
301    }
302}
303