001 /* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2013 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029 package edu.wisc.ssec.mcidasv.chooser; 030 031 import java.awt.Component; 032 import java.awt.Container; 033 import java.awt.event.ActionEvent; 034 import java.awt.event.ActionListener; 035 import java.beans.PropertyChangeEvent; 036 import java.beans.PropertyChangeListener; 037 import java.io.File; 038 import java.util.ArrayList; 039 import java.util.Collections; 040 import java.util.Vector; 041 042 import javax.swing.JComboBox; 043 import javax.swing.JFileChooser; 044 import javax.swing.JLabel; 045 import javax.swing.JPanel; 046 import javax.swing.filechooser.FileFilter; 047 048 import org.w3c.dom.Element; 049 050 import ucar.unidata.idv.chooser.IdvChooserManager; 051 import ucar.unidata.util.GuiUtils; 052 import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 053 054 public class HRITChooser extends FileChooser { 055 056 private static final long serialVersionUID = 1L; 057 058 private HRITFilter hf = null; 059 060 private JLabel channelLabel = McVGuiUtils.makeLabelRight("Data Channel:"); 061 062 /** 063 * Create the chooser with the given manager and xml 064 * 065 * @param mgr The manager 066 * @param root The xml 067 * 068 */ 069 070 public HRITChooser(IdvChooserManager mgr, Element root) { 071 super(mgr, root); 072 } 073 074 /** 075 * Make the file chooser 076 * 077 * @param path the initial path 078 * 079 * @return the file chooser 080 */ 081 082 protected JFileChooser doMakeFileChooser(String path) { 083 return new HRITFileChooser(path); 084 } 085 086 protected Vector<String> getAvailableHRITTypes(String path) { 087 if (path == null) path = "."; 088 089 ArrayList<String> al = new ArrayList<String>(); 090 Vector<String> v = new Vector<String>(); 091 File f = new File(path); 092 File [] files = null; 093 if (f.isDirectory()) { 094 files = f.listFiles( 095 new java.io.FileFilter() { 096 public boolean accept(File f) { 097 if ((f.getName().endsWith("__")) && (f.getName().matches(".*MSG[2-3].*"))) { 098 return true; 099 } else { 100 return false; 101 } 102 } 103 } 104 ); 105 } 106 if (files != null) { 107 for (int i = 0; i < files.length; i++) { 108 String channelStr = files[i].getName().substring(26, 32); 109 if (channelStr.equals("______")) continue; 110 channelStr = channelStr.replace("___", ""); 111 if (! al.contains(channelStr)) { 112 al.add(channelStr); 113 } 114 } 115 } 116 Collections.sort(al); 117 for (int i = 0; i < al.size(); i++) { 118 v.add(al.get(i)); 119 } 120 return v; 121 } 122 123 public class ImageTypeChooser extends JComboBox implements ActionListener, PropertyChangeListener { 124 125 private static final long serialVersionUID = 1L; 126 JFileChooser jfc = null; 127 128 public ImageTypeChooser(JFileChooser fc, String path) { 129 jfc = fc; 130 Vector<String> availableTypes = getAvailableHRITTypes(path); 131 if (availableTypes.size() == 1 && availableTypes.get(0) == ".") { 132 availableTypes.removeAllElements(); 133 } 134 reloadComboBox(availableTypes); 135 addActionListener(this); 136 McVGuiUtils.setComponentWidth(this, McVGuiUtils.Width.DOUBLE); 137 } 138 139 public void actionPerformed(ActionEvent e) { 140 JComboBox cb = (JComboBox) e.getSource(); 141 String newFilter = (String) cb.getSelectedItem(); 142 HRITFilter hFilter = (HRITFilter) jfc.getFileFilter(); 143 hFilter.setExtraFilter(newFilter); 144 jfc.rescanCurrentDirectory(); 145 } 146 147 public void reloadComboBox(Vector<String> v) { 148 removeAllItems(); 149 if (v != null) { 150 for (int i = 0; i < v.size(); i++) { 151 addItem(v.get(i)); 152 } 153 } 154 if (v == null || v.size() == 0) { 155 setEnabled(false); 156 channelLabel.setEnabled(false); 157 } 158 else { 159 setEnabled(true); 160 channelLabel.setEnabled(true); 161 } 162 } 163 164 public void propertyChange(PropertyChangeEvent e) { 165 String prop = e.getPropertyName(); 166 167 // If the directory changed, reload the combo box with new image type choices. 168 if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) { 169 Vector<String> availableTypes = getAvailableHRITTypes(jfc.getCurrentDirectory().getPath()); 170 reloadComboBox(availableTypes); 171 } 172 173 } 174 175 } 176 177 /* HRITFilter */ 178 public class HRITFilter extends FileFilter { 179 180 String extraFilter = null; 181 182 public HRITFilter(String extraFilter) { 183 super(); 184 if (extraFilter != null) { 185 this.extraFilter = extraFilter; 186 } 187 } 188 189 // Accept all directories and all HRIT files. 190 public boolean accept(File f) { 191 192 if (f.isDirectory()) { 193 return true; 194 } 195 196 // XXX TJJ - at present, we are ONLY allowing MSG2 and MSG3 segment data files 197 // through the filter which have already been Wavelet decompressed 198 // (i.e., they end with __ and not C_ ) 199 String fileName = f.getName(); 200 if ((fileName.endsWith("__")) && (fileName.matches(".*MSG[2-3].*")) && (fileName.length() >= 58)) { 201 if (extraFilter != null) { 202 if (fileName.contains(extraFilter)) { 203 return true; 204 } else { 205 return false; 206 } 207 } 208 } else { 209 return false; 210 } 211 return false; 212 213 } 214 215 // The description of this filter 216 public String getDescription() { 217 return "HRIT Data"; 218 } 219 220 // change the additional filter string 221 public void setExtraFilter(String newFilter) { 222 if (newFilter != null) { 223 extraFilter = newFilter; 224 //seenPatterns.clear(); 225 } 226 } 227 228 } 229 230 /** 231 * HRITFileChooser, an extension of JFileChooser 232 * 233 * @author Tommy Jasmin 234 */ 235 236 public class HRITFileChooser extends JFileChooser { 237 238 /** 239 * default for serializable class 240 */ 241 private static final long serialVersionUID = 1L; 242 243 /** 244 * Create the file chooser 245 * 246 * @param path the initial path 247 */ 248 249 public HRITFileChooser(String path) { 250 super(path); 251 setControlButtonsAreShown(false); 252 setMultiSelectionEnabled(false); 253 setAcceptAllFileFilterUsed(false); 254 processChildren(this); 255 } 256 257 private void processChildren(Container c) { 258 Component [] components = c.getComponents(); 259 if (components != null) { 260 // loop through all components, looking for the JLabel children of 261 // components we want to remove 262 for (int i = 0; i < components.length; i++) { 263 if (components[i] instanceof JLabel) { 264 String text = ((JLabel) components[i]).getText(); 265 if (text.equals("File Name:")) { 266 hideChildren((Container) components[i].getParent()); 267 continue; 268 } 269 if (text.equals("Files of Type:")) { 270 hideChildren((Container) components[i].getParent()); 271 continue; 272 } 273 } 274 // now check this component for any children 275 processChildren((Container) components[i]); 276 } 277 } 278 } 279 280 private void hideChildren(Container c) { 281 Component [] components = c.getComponents(); 282 for (int i = 0; i < components.length; i++) { 283 components[i].setVisible(false); 284 } 285 c.setVisible(false); 286 } 287 288 /** 289 * Approve the selection 290 */ 291 292 public void approveSelection() { 293 HRITChooser.this.doLoad(); 294 } 295 296 /** 297 * Cancel the selection 298 */ 299 300 public void cancelSelection() { 301 closeChooser(); 302 } 303 304 /** 305 * Set the selected files 306 * 307 * @param selectedFiles the selected files 308 */ 309 310 public void setSelectedFiles(File[] selectedFiles) { 311 String channelStr = null; 312 String timeStr = null; 313 if (selectedFiles != null) { 314 for (int i = 0; i < selectedFiles.length; i++) { 315 if (! selectedFiles[i].isDirectory()) { 316 if (selectedFiles[i].getName().length() >= 58) { 317 channelStr = selectedFiles[i].getName().substring(26, 32); 318 timeStr = selectedFiles[i].getName().substring(46, 58); 319 } 320 } 321 } 322 } 323 File curDir = getCurrentDirectory(); 324 File [] fileList = curDir.listFiles(); 325 String tmpChannel = null; 326 String tmpTime = null; 327 ArrayList<File> matches = new ArrayList<File>(); 328 for (int i = 0; i < fileList.length; i++) { 329 if ((fileList[i].getName().endsWith("__")) && 330 (fileList[i].getName().matches(".*MSG[2-3].*")) && 331 (fileList[i].getName().length() >= 58)) { 332 tmpChannel = fileList[i].getName().substring(26, 32); 333 tmpTime = fileList[i].getName().substring(46, 58); 334 if ((tmpChannel.equals(channelStr)) && (tmpTime.equals(timeStr))) { 335 matches.add(fileList[i]); 336 } 337 } 338 } 339 Collections.sort(matches); 340 341 // make new file array from ArrayList matches 342 File [] fileSet = new File[matches.size()]; 343 for (int i = 0; i < matches.size(); i++) { 344 fileSet[i] = (File) matches.get(i); 345 } 346 347 super.setSelectedFiles(fileSet); 348 setHaveData( !((selectedFiles == null) 349 || (selectedFiles.length == 0))); 350 } 351 } 352 353 /** 354 * Handle the selection of the set of files 355 * 356 * @param files The files the user chose 357 * @param directory The directory they chose them from 358 * @return True if the file was successful 359 * @throws Exception 360 */ 361 362 protected boolean selectFilesInner(File[] files, File directory) 363 throws Exception { 364 if ((files == null) || (files.length == 0)) { 365 userMessage("Please select a file"); 366 return false; 367 } 368 369 // only allow selection of files that make sense as a "set" 370 // for now, that means all part of single image for a single channel 371 String channelStr = files[0].getName().substring(26, 32); 372 String timeStr = files[0].getName().substring(46, 58); 373 int prvSegment = -1; 374 int curSegment = -1; 375 for (int i = 0; i < files.length; i++) { 376 try { 377 curSegment = Integer.parseInt(files[i].getName().substring(40, 42)); 378 } catch (NumberFormatException nfe) { 379 userMessage("Problem determining image segment number for file: " + files[i].getName()); 380 return false; 381 } 382 if (!files[i].getName().substring(26, 32).equals(channelStr)) { 383 userMessage("Selected data must be for a single channel and time"); 384 return false; 385 } 386 if (!files[i].getName().substring(46, 58).equals(timeStr)) { 387 userMessage("Selected data must be for a single channel and time"); 388 return false; 389 } 390 if (prvSegment >= 0) { 391 if (curSegment != (prvSegment + 1)) { 392 userMessage("Selected data must be a contiguous set of image segment files"); 393 return false; 394 } 395 } 396 prvSegment = curSegment; 397 } 398 399 // XXX TJJ - until HRITAdapter can handle the fact that HRV data can 400 // alter geographic coverage in mid-transmission, we deal with this by 401 // only allowing display of HRV segments one at a time. 402 403 // commenting out for now - will deal with it in field selector window 404 /* if (files.length > 1) { 405 int hrvCount = 0; 406 for (int i = 0; i < files.length; i++) { 407 if (files[i].getName().contains("HRV")) { 408 hrvCount++; 409 } 410 if (hrvCount > 1) { 411 userMessage("At present, HRV data can only be displayed one file at a time"); 412 return false; 413 } 414 } 415 }*/ 416 417 return super.selectFilesInner(files, directory); 418 } 419 420 /** 421 * Get the bottom panel for the chooser 422 * @return the bottom panel 423 */ 424 425 protected JPanel getBottomPanel() { 426 // If we don't have a fileChooser yet, this won't do any good 427 // This happens when Unidata's FileChooser is instantiated 428 // We instantiate ours right after that 429 if (fileChooser == null) { 430 return null; 431 } 432 433 ImageTypeChooser itc = new ImageTypeChooser(fileChooser, path); 434 fileChooser.addPropertyChangeListener(itc); 435 JPanel bottomPanel = GuiUtils.left(itc); 436 bottomPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); 437 438 return McVGuiUtils.makeLabeledComponent(channelLabel, itc); 439 } 440 441 /** 442 * Get the center panel for the chooser 443 * @return the center panel 444 */ 445 446 protected JPanel getCenterPanel() { 447 JPanel centerPanel = super.getCenterPanel(); 448 449 fileChooser.setAcceptAllFileFilterUsed(false); 450 451 // see what HRIT data is available in this directory, 452 Vector<String> availableTypes = getAvailableHRITTypes(path); 453 String extraFilter = null; 454 if ((availableTypes != null) && (availableTypes.size() > 0)) { 455 extraFilter = (String) availableTypes.get(0); 456 } 457 458 hf = new HRITFilter(extraFilter); 459 fileChooser.setFileFilter(hf); 460 461 return centerPanel; 462 } 463 464 }