001 /*
002 * $Id: SoundingFileBrowser.java,v 1.8 2012/02/19 17:35:36 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
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
031 package edu.wisc.ssec.mcidasv.chooser;
032
033
034 import ucar.unidata.beans.NonVetoableProperty;
035 import ucar.unidata.beans.Property;
036 import ucar.unidata.beans.PropertySet;
037 import ucar.unidata.data.sounding.CMASoundingAdapter;
038 import ucar.unidata.data.sounding.NetcdfSoundingAdapter;
039 import ucar.unidata.data.sounding.SoundingAdapter;
040
041
042 import ucar.unidata.util.FileManager;
043
044 import ucar.unidata.util.GuiUtils;
045 import ucar.unidata.util.LogUtil;
046 import ucar.unidata.util.Misc;
047 import ucar.unidata.util.PatternFileFilter;
048
049
050
051 import java.awt.Component;
052 import java.awt.Insets;
053 import java.awt.event.ActionEvent;
054 import java.awt.event.ActionListener;
055 import java.awt.event.WindowAdapter;
056 import java.awt.event.WindowEvent;
057 import java.awt.event.WindowListener;
058
059 import java.beans.*;
060
061 import java.io.File;
062
063 import javax.swing.BorderFactory;
064 import javax.swing.JButton;
065 import javax.swing.JFrame;
066 import javax.swing.JOptionPane;
067 import javax.swing.JPanel;
068 import 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.8 $
076 */
077 public 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