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