001/* 002 * $Id: Level2RadarChooser.java,v 1.6 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 org.w3c.dom.Element; 035 036import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 037 038import ucar.unidata.data.DataSource; 039 040import ucar.unidata.data.DataSourceDescriptor; 041import ucar.unidata.data.radar.Level2RadarDataSource; 042 043import ucar.unidata.idv.*; 044import ucar.unidata.idv.chooser.IdvChooserManager; 045import ucar.unidata.idv.control.DisplayControlBase; 046 047import ucar.unidata.metdata.*; 048 049import ucar.unidata.ui.ChooserPanel; 050import ucar.unidata.util.FileManager; 051import ucar.unidata.util.GuiUtils; 052import ucar.unidata.util.Misc; 053 054import ucar.unidata.util.PatternFileFilter; 055import ucar.unidata.util.PollingInfo; 056import ucar.unidata.util.TwoFacedObject; 057import ucar.unidata.xml.XmlResourceCollection; 058 059 060import ucar.unidata.xml.XmlUtil; 061 062import java.awt.*; 063import java.awt.event.*; 064 065import java.io.File; 066 067import java.util.ArrayList; 068import java.util.Collections; 069import java.util.Hashtable; 070import java.util.Iterator; 071import java.util.List; 072import java.util.Map; 073import java.util.Vector; 074 075import javax.swing.*; 076import javax.swing.event.*; 077 078import javax.swing.filechooser.FileFilter; 079 080 081 082/** 083 * A chooser for Level II NEXRAD data. This loads in 084 * files from the file system. Since (right now) the 085 * data does not contain the station we rely on 086 * the heuristic of looking at the directory path 087 * name to see if it contains a station name. 088 * The user can also specify the station from the GUI 089 * 090 * 091 * @author IDV development team 092 * @version $Revision: 1.6 $Date: 2011/03/24 16:06:31 $ 093 */ 094public class Level2RadarChooser extends FileChooser { 095 096 /** Holds the predefined list of nexrad stations */ 097 private JComboBox stationsCbx; 098 099 /** List of predefined nexrad stations */ 100 private List nexradStations; 101 102 /** Label used in the widgets to show an unknown station */ 103 private static String UNKNOWN_STATION = "I'm Feeling Lucky"; 104 105 /** 106 * The data source id we pass the files to. 107 * This is the oone defined in idv/resources/datasources.xml 108 */ 109 private static String DATA_TYPE = "FILE.LEVEL2RADAR"; 110 111 /** the type for the CDM radar */ 112 private static String CDM_DATA_TYPE = "FILE.RADAR"; 113 114 /** checkbox for switching data types */ 115 private JCheckBox typeCbx; 116 117 /** 118 * Create the chooser with the given chooser manager 119 * and xml root (from the xml that defines this chooser). 120 * 121 * @param mgr The manager 122 * @param root The xml 123 * 124 */ 125 public Level2RadarChooser(IdvChooserManager mgr, Element root) { 126 super(mgr, root); 127 } 128 129 /** 130 * Label for getDataSourcesComponent selector 131 * @return 132 */ 133 protected String getDataSourcesLabel() { 134 return "Station:"; 135 } 136 137 /** 138 * Overridden so that McIDAS-V can attempt auto-selecting the default data 139 * source type. 140 */ 141 @Override protected JComboBox getDataSourcesComponent() { 142 stationsCbx = new JComboBox(); 143 List stations = Misc.newList(UNKNOWN_STATION); 144 stations.addAll(nexradStations = getStations()); 145 DisplayControlBase.setStations(stations, stationsCbx, false); 146 return stationsCbx; 147 } 148 149 /** 150 * Get the tooltip for the load button 151 * 152 * @return The tooltip for the load button 153 */ 154 protected String getLoadToolTip() { 155 return "Load the selected Level II radar files"; 156 } 157 158 /** 159 * Make the file chooser 160 * 161 * @param path the initial path 162 * 163 * @return the JFileChooser 164 */ 165 protected JFileChooser doMakeFileChooser(String path) { 166 MyFileChooser fileChooser = new Level2RadarFileChooser(this, path); 167 fileChooser.addChoosableFileFilter(new PatternFileFilter(".*\\.raw$", "Raw files")); 168// fileChooser.setApproveButtonText(ChooserPanel.CMD_LOAD); 169 fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter()); 170 if (path != null) { 171 fileChooser.setCurrentDirectory(new File(path)); 172 } 173 return fileChooser; 174 } 175 176 /** 177 * Process the set of selected files 178 * 179 * @param files Array of files 180 * @param directory The last directory chosen 181 * 182 * @return true if successful 183 */ 184 protected boolean selectFilesInner(File[] files, final File directory) { 185 final Object selected = 186 ((TwoFacedObject) stationsCbx.getSelectedItem()).getId(); 187 188 if (selected.equals(UNKNOWN_STATION) 189 && ((typeCbx != null) && !typeCbx.isSelected())) { 190 userMessage("Unknown location of selected files, " 191 + "please select from list"); 192 return false; 193 } 194 195 int recentCnt = getFileCount(); 196 if (recentCnt <= 0) { 197 if ((files == null) || (files.length == 0)) { 198 userMessage("Please select one or more files"); 199 return false; 200 } 201 } 202 if ((files != null) && (files.length > 0)) { 203 FileManager.addToHistory(files[0]); 204 } 205 206 String[] tmpDataLoc = getFileNames(((recentCnt <= 0) 207 ? files 208 : null)); 209 if (recentCnt <= 0) { 210 if (tmpDataLoc == null) { 211 return false; 212 } 213 } 214 215 final Hashtable properties = 216 Misc.newHashtable(Level2RadarDataSource.STATION_LOCATION, 217 selected); 218 String pattern = getFilePattern(); 219 if ((pattern != null) && (pattern.length() > 0)) { 220 properties.put(DataSource.PROP_FILEPATTERN, 221 pattern.toLowerCase()); 222 } else { 223 pattern = null; 224 } 225 226 if (recentCnt > 0) { 227 properties.put(DataSource.MOST_RECENT, new Integer(recentCnt)); 228 tmpDataLoc = new String[] { directory.toString() }; 229 PollingInfo pollingInfo = new PollingInfo(directory.toString(), 230 60000, pattern, false, false); 231 pollingInfo.setMode(PollingInfo.MODE_COUNT); 232 pollingInfo.setFileCount(recentCnt); 233 properties.put(DataSource.PROP_POLLINFO, pollingInfo); 234 } 235 236 String dataType = ((typeCbx != null) && !typeCbx.isSelected()) 237 ? DATA_TYPE 238 : CDM_DATA_TYPE; 239 // System.out.println("dataType = " + dataType); 240 makeDataSource(tmpDataLoc, dataType, properties); 241 return true; 242 } 243 244 /** 245 * Read in the nexrad stations from the 246 * idv/resources/nexradstns.xml resource 247 * 248 * @return List of of {@link ucar.unidata.metdata.NamedStation}-s 249 */ 250 private List getStations() { 251 if (nexradStations == null) { 252 nexradStations = new Vector(); 253 List radarLocations = 254 getIdv().getResourceManager().findLocationsByType("radar"); 255 for (int i = 0; i < radarLocations.size(); i++) { 256 NamedStationTable nexrTable = 257 (NamedStationTable) radarLocations.get(i); 258 nexradStations.addAll(nexrTable.values()); 259 } 260 Collections.sort(nexradStations); 261 } 262 return nexradStations; 263 } 264 265 /** 266 * Try to guess at the station of the selected 267 * file based on directory name. 268 * 269 * @param file The selected file 270 */ 271 protected void guessAtStation(File file) { 272 273 if ((file == null) || !file.isDirectory()) { 274 return; 275 } 276 if ((nexradStations == null) || nexradStations.isEmpty()) { 277 return; 278 } 279 File tmpFile = file; 280 281 //Walk up the directory tree, looking at the names of each file 282 283 //Use the dirLevel so we only do the println on the first check. 284 //Though we could use it to only check one or two directory levels 285 int dirLevel = 0; 286 boolean found = false; 287 while ((tmpFile != null) && (found == false)) { 288 String name = tmpFile.getName().toLowerCase(); 289 for (Iterator iter = 290 nexradStations.iterator(); iter.hasNext(); ) { 291 NamedStation station = (NamedStation) iter.next(); 292 if (station == null) { 293 continue; 294 } 295 296 String id = station.getIdentifier(); 297 //Do a .equals - perhaps we do want to do the .indexOf check?? 298 //Though that might mean some odd matches. 299 if (name.indexOf(id.toLowerCase()) >= 0) { 300 stationsCbx.setSelectedItem( 301 DisplayControlBase.createStationTfo(station)); 302 found = true; 303 break; 304 } 305 } 306 dirLevel++; 307 tmpFile = tmpFile.getParentFile(); 308 } 309 if ( !found) { 310 stationsCbx.setSelectedItem(UNKNOWN_STATION); 311 } 312 } 313 314 /** 315 * This class allows us to add in our own functionality 316 * to the file chooser. It has a hook to support the guessing 317 * of the station from the directory name and passes through 318 * to the chooser the select and cancel events 319 * 320 * @author IDV development team 321 */ 322 public class Level2RadarFileChooser extends FileChooser.MyFileChooser { 323 324 /** my chooser */ 325 Level2RadarChooser myChooser; 326 327 /** Keeps track of the last directory the user chose */ 328 File lastDirectory = null; 329 330 /** 331 * Create the special file chooser 332 * 333 * 334 * @param chooser the chooser to relate to 335 * @param path path to start with 336 */ 337 public Level2RadarFileChooser(Level2RadarChooser chooser, 338 String path) { 339 super(path); 340 myChooser = chooser; 341 } 342 343 /** 344 * Try to guess at the station name 345 * 346 * @param file The currently selected dir 347 */ 348 public void setCurrentDirectory(File file) { 349 super.setCurrentDirectory(file); 350 if ( !Misc.equals(file, lastDirectory)) { 351 if (myChooser != null) { 352 myChooser.guessAtStation(file); 353 } 354 lastDirectory = file; 355 } 356 } 357 } 358 359 /** 360 * Get the bottom panel for the chooser 361 * @return the bottom panel 362 */ 363 protected JPanel getBottomPanel() { 364 // do this because the original check is made before the list is inited 365 if (getFileChooser() != null) { 366 guessAtStation(getFileChooser().getCurrentDirectory()); 367 } 368 JComponent recentComponent = getRecentFilesComponent(); 369 Component [] components = recentComponent.getComponents(); 370 if (components != null) { 371 for (int i = 0; i < components.length; i++) { 372 if (components[i] instanceof JLabel) { 373 McVGuiUtils.setComponentWidth((JLabel)components[i], McVGuiUtils.Width.SINGLE); 374 McVGuiUtils.setLabelPosition((JLabel)components[i], McVGuiUtils.Position.RIGHT); 375 } 376 else if (components[i] instanceof JComboBox) { 377 McVGuiUtils.setComponentWidth((JComboBox)components[i], McVGuiUtils.Width.DOUBLE); 378 } 379 else if (components[i] instanceof JTextField) { 380 McVGuiUtils.setComponentWidth((JTextField)components[i], McVGuiUtils.Width.SINGLE); 381 } 382 } 383 recentComponent = GuiUtils.left(GuiUtils.hbox(components)); 384 } 385 return McVGuiUtils.makeLabeledComponent("Times:", recentComponent); 386 } 387 388} 389