001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2017 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 029package edu.wisc.ssec.mcidasv.chooser.adde; 030 031import static javax.swing.GroupLayout.DEFAULT_SIZE; 032import static javax.swing.GroupLayout.PREFERRED_SIZE; 033import static javax.swing.GroupLayout.Alignment.BASELINE; 034import static javax.swing.GroupLayout.Alignment.LEADING; 035import static javax.swing.KeyStroke.getKeyStroke; 036import static javax.swing.LayoutStyle.ComponentPlacement.RELATED; 037 038import java.awt.BorderLayout; 039import java.awt.Color; 040import java.awt.Component; 041import java.awt.IllegalComponentStateException; 042import java.awt.Insets; 043import java.awt.Point; 044import java.awt.event.ActionEvent; 045import java.awt.event.ActionListener; 046import java.awt.event.KeyEvent; 047import java.awt.event.KeyListener; 048import java.text.SimpleDateFormat; 049import java.util.ArrayList; 050import java.util.Arrays; 051import java.util.Collections; 052import java.util.Date; 053import java.util.Hashtable; 054import java.util.Iterator; 055import java.util.List; 056import java.util.StringTokenizer; 057import java.util.Vector; 058import java.util.regex.Matcher; 059import java.util.regex.Pattern; 060 061import javax.swing.GroupLayout; 062import javax.swing.JButton; 063import javax.swing.JCheckBox; 064import javax.swing.JComboBox; 065import javax.swing.JComponent; 066import javax.swing.JDialog; 067import javax.swing.JLabel; 068import javax.swing.JOptionPane; 069import javax.swing.JPanel; 070import javax.swing.JSlider; 071import javax.swing.JTextField; 072import javax.swing.JToggleButton; 073import javax.swing.KeyStroke; 074import javax.swing.event.ChangeEvent; 075import javax.swing.event.ChangeListener; 076 077import org.slf4j.Logger; 078import org.slf4j.LoggerFactory; 079import org.w3c.dom.Element; 080 081import ucar.unidata.data.DataSelection; 082import ucar.unidata.data.imagery.AddeImageDescriptor; 083import ucar.unidata.data.imagery.AddeImageInfo; 084import ucar.unidata.data.imagery.BandInfo; 085import ucar.unidata.data.imagery.ImageDataSource; 086import ucar.unidata.data.imagery.ImageDataset; 087import ucar.unidata.idv.IdvResourceManager; 088import ucar.unidata.idv.chooser.IdvChooserManager; 089import ucar.unidata.idv.chooser.adde.AddeServer; 090import ucar.unidata.ui.LatLonWidget; 091import ucar.unidata.util.Format; 092import ucar.unidata.util.GuiUtils; 093import ucar.unidata.util.LogUtil; 094import ucar.unidata.util.Misc; 095import ucar.unidata.util.StringUtil; 096import ucar.unidata.util.TwoFacedObject; 097import ucar.unidata.xml.XmlNodeList; 098import ucar.unidata.xml.XmlResourceCollection; 099import ucar.unidata.xml.XmlUtil; 100import ucar.visad.UtcDate; 101 102import visad.DateTime; 103import visad.Gridded1DSet; 104import visad.VisADException; 105 106import edu.wisc.ssec.mcidas.AreaDirectory; 107import edu.wisc.ssec.mcidas.AreaDirectoryList; 108import edu.wisc.ssec.mcidas.McIDASException; 109import edu.wisc.ssec.mcidas.adde.AddeSatBands; 110import edu.wisc.ssec.mcidas.adde.AddeURL; 111import edu.wisc.ssec.mcidas.adde.AddeURLException; 112import edu.wisc.ssec.mcidasv.servermanager.EntryStore; 113import edu.wisc.ssec.mcidasv.ui.JCalendarDateEditor; 114import edu.wisc.ssec.mcidasv.ui.JCalendarPicker; 115import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 116 117/** 118 * Widget to select images from a remote ADDE server Displays a list of the 119 * descriptors (names) of the image datasets available for a particular ADDE 120 * group on the remote server. 121 * 122 * @author Don Murray 123 */ 124 125public class AddeImageChooser extends AddeChooser implements 126 ucar.unidata.ui.imagery.ImageSelector { 127 128 private static final Logger logger = LoggerFactory.getLogger(AddeImageChooser.class); 129 130 // TODO: get rid of this button right? 131 public static JToggleButton mineBtn = GuiUtils 132 .getToggleImageButton( 133 "/edu/wisc/ssec/mcidasv/resources/icons/toolbar/internet-web-browser16.png", 134 "/edu/wisc/ssec/mcidasv/resources/icons/toolbar/system-software-update16.png", 135 0, 0, true); 136 137 /** _more_ */ 138 public static final int SIZE_THRESHOLD = 50; 139 140 /** default magnification */ 141 private static final int DEFAULT_MAG = 0; 142 143 /** flag for center */ 144 private static final String PLACE_CENTER = "CENTER"; 145 146 /** flag for upper left */ 147 private static final String PLACE_ULEFT = "ULEFT"; 148 149 /** flag for lower left */ 150 private static final String PLACE_LLEFT = "LLEFT"; 151 152 /** flag for upper right */ 153 private static final String PLACE_URIGHT = "URIGHT"; 154 155 /** flag for lower right */ 156 private static final String PLACE_LRIGHT = "LRIGHT"; 157 158 /** Property for the satband file */ 159 protected static final String FILE_SATBAND = "SATBAND"; 160 161 /** Property for image default value band */ 162 protected static final String PROP_BAND = "BAND"; 163 164 /** Property for image default value id */ 165 protected static final String PROP_ID = "ID"; 166 167 /** Property for image default value key */ 168 protected static final String PROP_KEY = "key"; 169 170 /** Property for image default value lat/lon */ 171 protected static final String PROP_LATLON = "LATLON"; 172 173 /** Property for image default value line/ele */ 174 protected static final String PROP_LINELE = "LINELE"; 175 176 /** Property for image default value loc */ 177 protected static final String PROP_LOC = "LOC"; 178 179 /** Property for image default value mag */ 180 protected static final String PROP_MAG = "MAG"; 181 182 /** Property for num */ 183 protected static final String PROP_NUM = "NUM"; 184 185 /** Property for image default value place */ 186 protected static final String PROP_PLACE = "PLACE"; 187 188 /** Property for image default value size */ 189 protected static final String PROP_SIZE = "SIZE"; 190 191 /** Property for image default value spac */ 192 protected static final String PROP_SPAC = "SPAC"; 193 194 /** Property for image default value unit */ 195 protected static final String PROP_UNIT = "UNIT"; 196 197 /** Property for image default value unit */ 198 protected static final String PROP_NAV = "NAV"; 199 200 /** This is the list of properties that are used in the advanced gui */ 201 private static final String[] ADVANCED_PROPS = { PROP_UNIT, PROP_BAND, 202 PROP_PLACE, PROP_LOC, PROP_SIZE, PROP_MAG, PROP_NAV }; 203 204 /** This is the list of labels used for the advanced gui */ 205 private static final String[] ADVANCED_LABELS = { "Data Type:", "Channel:", 206 "Placement:", "Location:", "Image Size:", "Magnification:", 207 "Navigation Type:" }; 208 209 /** Xml tag name for the defaults */ 210 protected static final String TAG_DEFAULT = "default"; 211 212 /** identifiere for the default value */ 213 protected static final String VALUE_DEFAULT = "default"; 214 215 /** Xml attr name for the defaults */ 216 protected static final String ATTR_NAME = "name"; 217 218 /** Xml attr name for the defaults */ 219 protected static final String ATTR_PATTERN = "pattern"; 220 221 /** flag for setting properties */ 222 private boolean amSettingProperties = false; 223 224 /** Are we currently reading times */ 225 private Object readTimesTask; 226 227 /** archive date */ 228 protected String archiveDay = null; 229 230 /** number of image times to list */ 231 protected String numTimes = "all"; 232 233 /** Holds the properties */ 234 private JPanel propPanel; 235 236 /** Archive day selector button. */ 237 protected JButton archiveDayBtn; 238 239 protected JButton numImagesButton; 240 241 protected JTextField imageCountTextField; 242 243 /** Maps the PROP_ property name to the gui component */ 244 private Hashtable propToComps = new Hashtable(); 245 246 /** 247 * This is a list of hashtables, one per imagedefaults resource. The 248 * Hashtables map the pattern to the xml node 249 */ 250 private List resourceMaps; 251 252 /** Holds the subsetting defaults */ 253 private XmlResourceCollection addeDefaults; 254 255 /** archive date formatter */ 256 private SimpleDateFormat archiveDayFormatter; 257 258 /** Input for lat/lon center point */ 259 protected LatLonWidget latLonWidget; 260 261 /** Widget for the line magnfication in the advanced section */ 262 protected JSlider lineMagSlider; 263 264 /** Label for the line mag. in the advanced section */ 265 protected JLabel lineMagLbl; 266 267 /** Widget for the element magnfication in the advanced section */ 268 protected JSlider elementMagSlider; 269 270 /** Label for the element mag. in the advanced section */ 271 protected JLabel elementMagLbl; 272 273 /** base number of lines */ 274 private double baseNumLines = 0.0; 275 276 /** size label */ 277 JLabel sizeLbl; 278 279 /** base number of lines */ 280 private double baseNumElements = 0.0; 281 282 /** Widget to hold the number of elements in the advanced */ 283 JTextField numElementsFld; 284 285 /** Widget to hold the number of lines in the advanced */ 286 JTextField numLinesFld; 287 288 /** Widget for the line center point in the advanced section */ 289 protected JTextField centerLineFld; 290 291 /** Widget for the element center point in the advanced section */ 292 protected JTextField centerElementFld; 293 294 /** _more_ */ 295 private JToggleButton lockBtn; 296 297 /** full resolution button */ 298 private JButton fullResBtn; 299 300 /** Identifier for the maximum number of bands */ 301 int MAX_BANDS = 100; 302 303 /** The last AreaDirectory we have seen. */ 304 private AreaDirectory lastAD; 305 306 /** The current AreaDirectory used for properties */ 307 private AreaDirectory propertiesAD; 308 309 /** The previous AreaDirectory used for properties */ 310 private AreaDirectory prevPropertiesAD; 311 312 /** Mapping of area directory to list of BandInfos */ 313 protected Hashtable bandTable; 314 315 /** Mapping of band index to {@link edu.wisc.ssec.mcidas.AreaDirectory}. */ 316 protected Hashtable bandDirs; 317 318 /** 319 * The list of currently loaded AddeImageDescriptor-s 320 */ 321 protected Vector imageDescriptors; 322 323 /** maximum size for the widget */ 324 private static final int MAX_SIZE = 700; 325 326 /** Widget for selecting image units */ 327 protected JComboBox unitComboBox; 328 329 /** place label */ 330 private JLabel placeLbl; 331 332 /** the place string */ 333 private String place; 334 335 /** location panel */ 336 private GuiUtils.CardLayoutPanel locationPanel; 337 338 /** Widget for selecting image nav type */ 339 protected JComboBox navComboBox; 340 341 /** 342 * Mapping of sensor id (String) to hashtable that maps Integer band number 343 * to name 344 */ 345 private Hashtable sensorToBandToName; 346 347 /** A flag so we can debug the new way of processing sat band file */ 348 private boolean useSatBandInfo = true; 349 350 /** Used to parse the sat band file */ 351 private AddeSatBands satBandInfo; 352 353 /** Widget for selecting the band */ 354 protected JComboBox bandComboBox; 355 356 /** string for ALL */ 357 protected static final String ALL = "ALL"; 358 359 /** object for selecting all bands */ 360 protected static final TwoFacedObject ALLBANDS = new TwoFacedObject( 361 "All Bands", ALL); 362 363 /** object for selecting all calibrations */ 364 protected static final TwoFacedObject ALLUNITS = new TwoFacedObject( 365 "All Types", ALL); 366 367 /** 368 * Keep track of the lines to element ratio 369 */ 370 private double linesToElements = 1.0; 371 372 /** 373 * limit of slider 374 */ 375 private static final int SLIDER_MAX = 29; 376 377 private static final String DEFAULT_ARCHIVE_IMAGE_COUNT = "100"; 378 379 /** 380 * the list of band infos 381 */ 382 private List<BandInfo> bandInfos; 383 384 /** 385 * Construct an Adde image selection widget 386 * 387 * 388 * @param mgr 389 * The chooser manager 390 * @param root 391 * The chooser.xml node 392 */ 393 public AddeImageChooser(IdvChooserManager mgr, Element root) { 394 super(mgr, root); 395// AnnotationProcessor.process(this); 396 addDescComp(loadButton); 397 398 archiveDayBtn = new JButton("Select Day"); 399 archiveDayBtn.addActionListener(e -> getArchiveDay()); 400 archiveDayBtn.setToolTipText("Select a day for archive datasets"); 401 402 numImagesButton = new JButton("List Images"); 403 numImagesButton.addActionListener(e -> readTimes(false)); 404 numImagesButton.setToolTipText("<html>By default, up to the 100 most " + 405 "recent times are listed.<br/><br/>For a different image count, " + 406 "provide a positive integer in<br/>the adjacent text box, " + 407 "or \"ALL\" for ALL relevant times.<br/><br/>Choosing ALL may be slow for" + 408 " datasets with many times.</html>"); 409 410 // Initialize the image count to default 411 imageCountTextField = new JTextField(AddeImageChooser.DEFAULT_ARCHIVE_IMAGE_COUNT, 4); 412 imageCountTextField.setToolTipText("<html>By default, up to the 100 most " + 413 "recent times are listed.<br/><br/>You may set this field to any positive " + 414 "integer, or the value ALL.<br/>Using ALL may take awhile for" + 415 " datasets with many times.</html>"); 416 417 this.addeDefaults = getImageDefaults(); 418 } 419 420 /** 421 * Number of absolute times to list in the chooser. 422 * Must be a positive integer, or the word "ALL". 423 * Will throw up a dialog for invalid entries. 424 * 425 * @return 0 for valid entries, -1 for invalid 426 */ 427 428 private int parseImageCount() { 429 String countStr = imageCountTextField.getText(); 430 try { 431 int newCount = Integer.parseInt(countStr); 432 // Make sure it's reasonable 433 if (newCount > 0) { 434 int addeParam = 0 - newCount + 1; 435 numTimes = "" + addeParam; 436 } else { 437 throw new NumberFormatException(); 438 } 439 } catch (NumberFormatException nfe) { 440 // Still ok if they entered "ALL" 441 if (imageCountTextField.getText().isEmpty()) { 442 JOptionPane.showMessageDialog(this, 443 "Empty field, please enter a valid positive integer"); 444 return -1; 445 } 446 if (! imageCountTextField.getText().equalsIgnoreCase("all")) { 447 JOptionPane.showMessageDialog(this, 448 "Invalid entry: " + imageCountTextField.getText()); 449 return -1; 450 } 451 numTimes = imageCountTextField.getText(); 452 } 453 return 0; 454 } 455 456 /** 457 * Get the xml resource collection that defines the image default xml 458 * 459 * @return Image defaults resources 460 */ 461 protected XmlResourceCollection getImageDefaults() { 462 return getIdv().getResourceManager().getXmlResources( 463 IdvResourceManager.RSC_IMAGEDEFAULTS); 464 } 465 466 /** 467 * Update labels, enable widgets, etc. 468 */ 469 @Override protected void updateStatus() { 470 super.updateStatus(); 471 if (getDoAbsoluteTimes()) { 472 setPropertiesState(getASelectedTime()); 473 } else { 474 setPropertiesState(lastAD); 475 } 476 477 if (readTimesTask != null) { 478 if (taskOk(readTimesTask)) { 479 setStatus("Reading available times from server"); 480 } 481 } else if ((getState() == STATE_CONNECTED) && getDoAbsoluteTimes() && !haveTimeSelected() && haveDescriptorSelected()) { 482 setStatus(MSG_TIMES); 483 } 484 enableWidgets(); 485 } 486 487 /** 488 * Do we have times selected. Either we are doing absolute times and there 489 * are some selected in the list. Or we are doing relative times and we have 490 * done a connect to the server 491 * 492 * @return Do we have times 493 */ 494 public boolean timesOk() { 495 if (getDoAbsoluteTimes() && !haveTimeSelected()) { 496 return false; 497 } 498 return (lastAD != null); 499 } 500 501 /** 502 * Get the list of advanced property names 503 * 504 * @return array of advanced property names 505 */ 506 protected String[] getAdvancedProps() { 507 return ADVANCED_PROPS; 508 } 509 510 /** 511 * Get the list of advanced property labels 512 * 513 * @return list of advanced property labels 514 */ 515 protected String[] getAdvancedLabels() { 516 return ADVANCED_LABELS; 517 } 518 519 /** 520 * Convenience method for lazy people who don't want to call 521 * {@link ucar.unidata.util.LogUtil#logException(String, Throwable)}. 522 * 523 * @param msg 524 * log message 525 * @param exc 526 * Exception to log 527 */ 528 @Override public void logException(String msg, Exception exc) { 529 LogUtil.logException(msg, exc); 530 } 531 532 /** 533 * This allows derived classes to provide their own name for labeling, etc. 534 * 535 * @return the dataset name 536 */ 537 @Override public String getDataName() { 538 return "Image Data"; 539 } 540 541 /** 542 * Get the descriptor widget label 543 * 544 * @return label for the descriptor widget 545 */ 546 @Override public String getDescriptorLabel() { 547 return "Image Type"; 548 } 549 550 /** 551 * Respond to a change in the descriptor list. 552 */ 553 protected void checkSetNav() { 554 String descriptor = getDescriptor(); 555 if (descriptor!=null) { 556 String[] suffixes = { "AMSU", "HIRS", "HRPT", "GAC", "LAC" }; 557 for (int i=0; i<suffixes.length; i++) { 558 Pattern p = Pattern.compile("N\\d\\d" + suffixes[i]); 559 Matcher m = p.matcher(descriptor); 560 if (m.find()) { 561 navComboBox.setSelectedIndex(1); 562 break; 563 } 564 } 565 } 566 } 567 568 /** 569 * Get the name of the dataset. 570 * 571 * @return descriptive name of the dataset. 572 */ 573 public String getDatasetName() { 574 StringBuffer buf = new StringBuffer(); 575 buf.append(getSelectedDescriptor()); 576 if (bandComboBox != null && bandComboBox.getItemCount() > 1) { 577 buf.append(" ("); 578 buf.append(bandComboBox.getSelectedItem()); 579 buf.append(")"); 580 } 581 return buf.toString(); 582 } 583 584 /** 585 * Check if we are ready to read times 586 * 587 * @return true if times can be read 588 */ 589 protected boolean canReadTimes() { 590 return haveDescriptorSelected(); 591 } 592 593 /** 594 * Handle when the user presses the update button 595 * 596 * @throws Exception 597 * On badness 598 */ 599 @Override public void handleUpdate() throws Exception { 600 if (getState() != STATE_CONNECTED) { 601 // If not connected then update the server list 602 updateServerList(); 603 } else { 604 // If we are already connected then update the rest of the chooser 605 descriptorChanged(); 606 } 607 updateStatus(); 608 } 609 610 /** 611 * Do server connection stuff... override this with type-specific methods 612 */ 613 @Override protected void readFromServer() { 614 archiveDay = null; 615 if (archiveDayBtn != null) { 616 archiveDayBtn.setText("Select Day"); 617 } 618 readSatBands(); 619 super.readFromServer(); 620 } 621 622 /** 623 * Overwrite base class method to clear out the lastAD member here. 624 */ 625 @Override protected void clearTimesList() { 626 lastAD = null; 627 super.clearTimesList(); 628 } 629 630 /** 631 * Show the archive dialog. This method is not meant to be called but is 632 * public by reason of implementation (or insanity). 633 */ 634 public void getArchiveDay() { 635 final JDialog dialog = GuiUtils.createDialog("Set Archive Day", true); 636 final JCalendarPicker picker = new JCalendarPicker(false); 637 if (archiveDay != null) { 638 if (archiveDayFormatter == null) { 639 archiveDayFormatter = new SimpleDateFormat(UtcDate.YMD_FORMAT); 640 } 641 Date d = null; 642 try { 643 d = archiveDayFormatter.parse(archiveDay); 644 picker.setDate(d); 645 } catch (Exception e) { 646 logException("parsing archive day " + archiveDay, e); 647 } 648 } 649 650 ActionListener listener = new ActionListener() { 651 public void actionPerformed(ActionEvent ae) { 652 String cmd = ae.getActionCommand(); 653 if (cmd.equals(GuiUtils.CMD_REMOVE)) { 654 archiveDay = null; 655 archiveDayBtn.setText("Select Day"); 656 setDoAbsoluteTimes(true); 657 descriptorChanged(); 658 } else if (cmd.equals(GuiUtils.CMD_OK)) { 659 try { 660 archiveDay = picker.getUserSelectedDay(); 661 archiveDayBtn.setText(archiveDay); 662 } catch (Exception e) { 663 } 664 // System.out.println("archiveDay = " + archiveDay); 665 setDoAbsoluteTimes(true); 666 descriptorChanged(); 667 } 668 dialog.dispose(); 669 } 670 }; 671 672 final JCalendarDateEditor dateEditor = 673 (JCalendarDateEditor)picker.getDateChooser().getDateEditor(); 674 dateEditor.getUiComponent().addKeyListener(new KeyListener() { 675 @Override public void keyTyped(KeyEvent e) { } 676 677 @Override public void keyPressed(KeyEvent e) { } 678 679 @Override public void keyReleased(KeyEvent e) { 680 if (!Color.RED.equals(dateEditor.getForeground())) { 681 KeyStroke stroke = 682 getKeyStroke(e.getKeyCode(), e.getModifiers()); 683 if (stroke.getKeyCode() == KeyEvent.VK_ENTER) { 684 try { 685 archiveDay = picker.getUserSelectedDay(); 686 archiveDayBtn.setText(archiveDay); 687 } catch (Exception ex) { 688 // nothing to do 689 } 690 setDoAbsoluteTimes(true); 691 descriptorChanged(); 692 dialog.dispose(); 693 } 694 } 695 } 696 }); 697 698 JPanel buttons = GuiUtils.makeButtons(listener, new String[] { 699 GuiUtils.CMD_OK, GuiUtils.CMD_REMOVE, GuiUtils.CMD_CANCEL }); 700 701 JComponent contents = GuiUtils.topCenterBottom(GuiUtils.inset(GuiUtils 702 .lLabel("Please select a day for this dataset:"), 10), GuiUtils 703 .inset(picker, 10), buttons); 704 Point p = new Point(200, 200); 705 if (archiveDayBtn != null) { 706 try { 707 p = archiveDayBtn.getLocationOnScreen(); 708 } catch (IllegalComponentStateException ice) { 709 } 710 } 711 dialog.setLocation(p); 712 dialog.getContentPane().add(contents); 713 dialog.pack(); 714 dialog.setVisible(true); 715 } 716 717 /** 718 * Add the bottom advanced gui panel to the list 719 * 720 * @param bottomComps 721 * the bottom components 722 */ 723 protected void getBottomComponents(List bottomComps) { 724 725 String[] propArray = getAdvancedProps(); 726 String[] labelArray = getAdvancedLabels(); 727 // List bottomComps = new ArrayList(); 728 Insets dfltGridSpacing = new Insets(4, 0, 4, 0); 729 String dfltLblSpacing = " "; 730 731 boolean haveBand = Misc.toList(propArray).contains(PROP_BAND); 732 boolean haveNav = Misc.toList(propArray).contains(PROP_NAV); 733 for (int propIdx = 0; propIdx < propArray.length; propIdx++) { 734 JComponent propComp = null; 735 String prop = propArray[propIdx]; 736 if (prop.equals(PROP_UNIT)) { 737 unitComboBox = new JComboBox(); 738 addPropComp(PROP_UNIT, propComp = unitComboBox); 739 GuiUtils.setPreferredWidth(unitComboBox, 100); 740 if (haveBand) { 741 bandComboBox = new JComboBox(); 742 bandComboBox.addActionListener(new ActionListener() { 743 public void actionPerformed(ActionEvent e) { 744 setAvailableUnits(propertiesAD, getSelectedBand()); 745 } 746 }); 747 addPropComp(PROP_BAND, bandComboBox); 748 749 propComp = GuiUtils.hbox(propComp, GuiUtils.inset( 750 new JLabel("Channel:"), new Insets(0, 10, 0, 5)), 751 bandComboBox, 5); 752 } 753 } else if (prop.equals(PROP_BAND)) { 754 // Moved to PROP_UNIT 755 } else if (prop.equals(PROP_PLACE)) { 756 // Moved to PROP_LOC 757 } else if (prop.equals(PROP_LOC)) { 758 placeLbl = GuiUtils.getFixedWidthLabel(""); 759 changePlace(PLACE_CENTER); 760 addPropComp(PROP_PLACE, placeLbl); 761 762 latLonWidget = new LatLonWidget(); 763 centerLineFld = new JTextField("", 3); 764 centerElementFld = new JTextField("", 3); 765 766 fullResBtn = GuiUtils.makeImageButton( 767 "/auxdata/ui/icons/arrow_out.png", this, 768 "setToFullResolution"); 769 fullResBtn.setContentAreaFilled(false); 770 fullResBtn.setToolTipText("Set to full resolution"); 771 772 // lockBtn = 773 // GuiUtils.getToggleImageButton(IdvUIManager.ICON_UNLOCK, 774 // IdvUIManager.ICON_LOCK, 0, 0, true); 775 // lockBtn.setContentAreaFilled(false); 776 // lockBtn.setSelected(true); 777 // lockBtn.setToolTipText( 778 // "Unlock to automatically change size when changing magnification"); 779 780 final JButton centerPopupBtn = GuiUtils.getImageButton( 781 "/auxdata/ui/icons/MapIcon16.png", getClass()); 782 centerPopupBtn.setToolTipText("Center on current displays"); 783 centerPopupBtn.addActionListener(new ActionListener() { 784 public void actionPerformed(ActionEvent ae) { 785 getIdv().getIdvUIManager().popupCenterMenu( 786 centerPopupBtn, latLonWidget); 787 } 788 }); 789 JComponent centerPopup = GuiUtils.inset(centerPopupBtn, 790 new Insets(0, 0, 0, 4)); 791 792 GuiUtils.tmpInsets = dfltGridSpacing; 793 final JPanel latLonPanel = GuiUtils.hbox(new Component[] { 794 GuiUtils.rLabel(" Lat:" + dfltLblSpacing), 795 latLonWidget.getLatField(), 796 GuiUtils.rLabel(" Lon:" + dfltLblSpacing), 797 latLonWidget.getLonField(), new JLabel(" "), 798 centerPopup }); 799 800 final JPanel lineElementPanel = GuiUtils.hbox(new Component[] { 801 GuiUtils.rLabel(" Line:" + dfltLblSpacing), 802 centerLineFld, 803 GuiUtils.rLabel(" Element:" + dfltLblSpacing), 804 centerElementFld }); 805 806 locationPanel = new GuiUtils.CardLayoutPanel(); 807 locationPanel.addCard(latLonPanel); 808 locationPanel.addCard(lineElementPanel); 809 810 JButton locPosButton = GuiUtils.makeImageButton( 811 "/auxdata/ui/icons/Refresh16.gif", this, "cyclePlace", 812 null, true); 813 814 locPosButton.setToolTipText("Change place type"); 815 816 JButton locTypeButton = GuiUtils.makeImageButton( 817 "/auxdata/ui/icons/Refresh16.gif", locationPanel, 818 "flip", null, true); 819 locTypeButton 820 .setToolTipText("Toggle between Latitude/Longitude and Line/Element"); 821 822 propComp = GuiUtils.hbox(new Component[] { locPosButton, 823 placeLbl, locTypeButton, locationPanel }, 5); 824 addPropComp(PROP_LOC, propComp); 825 } else if (prop.equals(PROP_MAG)) { 826 boolean oldAmSettingProperties = amSettingProperties; 827 amSettingProperties = true; 828 ChangeListener lineListener = new javax.swing.event.ChangeListener() { 829 public void stateChanged(ChangeEvent evt) { 830 if (amSettingProperties) { 831 return; 832 } 833 lineMagSliderChanged(!getLockButton().isSelected()); 834 } 835 }; 836 ChangeListener elementListener = new ChangeListener() { 837 public void stateChanged(javax.swing.event.ChangeEvent evt) { 838 if (amSettingProperties) { 839 return; 840 } 841 elementMagSliderChanged(true); 842 } 843 }; 844 JComponent[] lineMagComps = GuiUtils.makeSliderPopup( 845 -SLIDER_MAX, SLIDER_MAX, 0, lineListener); 846 lineMagSlider = (JSlider) lineMagComps[1]; 847 lineMagSlider.setMajorTickSpacing(1); 848 lineMagSlider.setSnapToTicks(true); 849 lineMagSlider.setExtent(1); 850 lineMagComps[0].setToolTipText("Change the line magnification"); 851 JComponent[] elementMagComps = GuiUtils.makeSliderPopup( 852 -SLIDER_MAX, SLIDER_MAX, 0, elementListener); 853 elementMagSlider = (JSlider) elementMagComps[1]; 854 elementMagSlider.setExtent(1); 855 elementMagSlider.setMajorTickSpacing(1); 856 elementMagSlider.setSnapToTicks(true); 857 elementMagComps[0] 858 .setToolTipText("Change the element magnification"); 859 lineMagSlider 860 .setToolTipText("Slide to set line magnification factor"); 861 lineMagLbl = GuiUtils.getFixedWidthLabel(StringUtil.padLeft( 862 "1", 4)); 863 elementMagSlider 864 .setToolTipText("Slide to set element magnification factor"); 865 elementMagLbl = GuiUtils.getFixedWidthLabel(StringUtil.padLeft( 866 "1", 4)); 867 amSettingProperties = oldAmSettingProperties; 868 869 GuiUtils.tmpInsets = dfltGridSpacing; 870 /* 871 * JPanel magPanel = GuiUtils.doLayout(new Component[] { 872 * GuiUtils.rLabel("Line:" + dfltLblSpacing), lineMagLbl, 873 * GuiUtils.inset(lineMagComps[0], new Insets(0, 4, 0, 0)), 874 * GuiUtils.rLabel(" Element:" + dfltLblSpacing), 875 * elementMagLbl, GuiUtils.inset(elementMagComps[0], new 876 * Insets(0, 4, 0, 0)), }, 6, GuiUtils.WT_N, GuiUtils.WT_N); 877 */ 878 /* 879 * JPanel magPanel = GuiUtils.doLayout(new Component[] { 880 * lineMagLbl, GuiUtils.inset(lineMagComps[0], new Insets(0, 4, 881 * 0, 0)), new JLabel(" X "), elementMagLbl, 882 * GuiUtils.inset(elementMagComps[0], new Insets(0, 4, 0, 0)), 883 * }, 6, GuiUtils.WT_N, GuiUtils.WT_N); 884 */ 885 886 JPanel magPanel = GuiUtils.doLayout( 887 new Component[] { 888 lineMagLbl, 889 GuiUtils.inset(lineMagComps[0], new Insets(0, 890 4, 0, 0)), 891 new JLabel(" X"), 892 elementMagLbl, 893 GuiUtils.inset(elementMagComps[0], new Insets( 894 0, 4, 0, 0)), 895 GuiUtils.inset(getLockButton(), new Insets(0, 896 10, 0, 0)) }, 7, GuiUtils.WT_N, 897 GuiUtils.WT_N); 898 899 addPropComp(PROP_MAG, propComp = magPanel); 900 if (haveNav) { 901 navComboBox = new JComboBox(); 902 GuiUtils.setListData(navComboBox, Misc.newList( 903 new TwoFacedObject("Default", "X"), 904 new TwoFacedObject("Lat/Lon", "LALO"))); 905 addPropComp(PROP_NAV, navComboBox); 906 boolean showNav = false; 907 showNav = getProperty("includeNavComp", false); 908 if (showNav) { 909 propComp = GuiUtils.hbox(propComp, GuiUtils.inset( 910 new JLabel("Navigation Type:"), new Insets(0, 911 10, 0, 5)), navComboBox, 5); 912 } 913 } 914 } else if (prop.equals(PROP_SIZE)) { 915 numLinesFld = new JTextField("", 4); 916 numElementsFld = new JTextField("", 4); 917 numLinesFld.setToolTipText("Number of lines"); 918 numElementsFld.setToolTipText("Number of elements"); 919 GuiUtils.tmpInsets = dfltGridSpacing; 920 sizeLbl = GuiUtils.lLabel(""); 921 922 /* 923 * JPanel sizePanel = GuiUtils.left(GuiUtils.doLayout(new 924 * Component[] { GuiUtils.rLabel("Lines:" + dfltLblSpacing), 925 * numLinesFld, GuiUtils.rLabel(" Elements:" + dfltLblSpacing), 926 * numElementsFld, new JLabel(" "), sizeLbl }, 6, GuiUtils.WT_N, 927 * GuiUtils.WT_N)); 928 */ 929 930 JPanel sizePanel = GuiUtils.left(GuiUtils.doLayout( 931 new Component[] { numLinesFld, new JLabel(" X "), 932 numElementsFld, fullResBtn, /* new JLabel(" "), */ 933 sizeLbl }, 5, GuiUtils.WT_N, GuiUtils.WT_N)); 934 addPropComp(PROP_SIZE, propComp = sizePanel); 935 } 936 937 if (propComp != null) { 938 bottomComps.add(GuiUtils.rLabel(labelArray[propIdx])); 939 bottomComps.add(GuiUtils.left(propComp)); 940 } 941 942 } 943 944 GuiUtils.tmpInsets = new Insets(3, 4, 0, 4); 945 propPanel = GuiUtils.doLayout(bottomComps, 2, GuiUtils.WT_N, 946 GuiUtils.WT_N); 947 enableWidgets(); 948 } 949 950 /** 951 * Get the "lock" button 952 * 953 * @return the lock button 954 */ 955 private JToggleButton getLockButton() { 956 if (lockBtn == null) { 957 lockBtn = GuiUtils.getToggleImageButton( 958 "/auxdata/ui/icons/Linked.gif", 959 "/auxdata/ui/icons/Unlinked.gif", 0, 0, true); 960 lockBtn.setContentAreaFilled(false); 961 lockBtn.setSelected(true); 962 lockBtn 963 .setToolTipText("Unlock to automatically change size when changing magnification"); 964 } 965 return lockBtn; 966 967 } 968 969 /** 970 * Set to full resolution 971 */ 972 public void setToFullResolution() { 973 974 if (propertiesAD == null) { 975 return; 976 } 977 amSettingProperties = true; 978 numLinesFld.setText("" + propertiesAD.getLines()); 979 numElementsFld.setText("" + propertiesAD.getElements()); 980 changePlace(PLACE_CENTER); 981 if (useLatLon()) { 982 locationPanel.flip(); 983 } 984 centerLineFld.setText("" + (propertiesAD.getLines() / 2)); 985 centerElementFld.setText("" + (propertiesAD.getElements() / 2)); 986 987 setMagSliders(1, 1); 988 amSettingProperties = false; 989 990 } 991 992 /** 993 * Cycle the place 994 */ 995 public void cyclePlace() { 996 if (place.equals(PLACE_CENTER)) { 997 changePlace(PLACE_ULEFT); 998 } else { 999 changePlace(PLACE_CENTER); 1000 } 1001 } 1002 1003 /** 1004 * Change the place 1005 * 1006 * @param newPlace 1007 * new place 1008 */ 1009 public void changePlace(String newPlace) { 1010 this.place = newPlace; 1011 String s = translatePlace(place) + "="; 1012 placeLbl.setText(StringUtil.padRight(s, 12)); 1013 } 1014 1015 /** 1016 * _more_ 1017 * 1018 * @param recomputeLineEleRatio 1019 * _more_ 1020 */ 1021 protected void elementMagSliderChanged(boolean recomputeLineEleRatio) { 1022 int value = getElementMagValue(); 1023 if ((Math.abs(value) < SLIDER_MAX)) { 1024 int lineMag = getLineMagValue(); 1025 if (lineMag > value) { 1026 linesToElements = Math.abs(lineMag / (double) value); 1027 } else { 1028 linesToElements = Math.abs((double) value / lineMag); 1029 } 1030 } 1031 // System.out.println(" changelistener: linesToElements = " + 1032 // linesToElements); 1033 elementMagLbl.setText(StringUtil.padLeft("" + value, 4)); 1034 if (!getLockButton().isSelected()) { 1035 if (value > 0) { 1036 numElementsFld.setText("" + (int) (baseNumElements * value)); 1037 } else { 1038 numElementsFld.setText("" 1039 + (int) (baseNumElements / (double) -value)); 1040 } 1041 } 1042 } 1043 1044 /** 1045 * Handle the line mag slider changed event 1046 * 1047 * 1048 * @param autoSetSize 1049 * _more_ 1050 */ 1051 protected void lineMagSliderChanged(boolean autoSetSize) { 1052 try { 1053 int value = getLineMagValue(); 1054 lineMagLbl.setText(StringUtil.padLeft("" + value, 4)); 1055 if (autoSetSize) { 1056 if (value > 0) { 1057 numLinesFld.setText("" + (int) (baseNumLines * value)); 1058 } else { 1059 numLinesFld.setText("" 1060 + (int) (baseNumLines / (double) -value)); 1061 } 1062 } 1063 1064 if (value == 1) { // special case 1065 if (linesToElements < 1.0) { 1066 value = (int) (-value / linesToElements); 1067 } else { 1068 value = (int) (value * linesToElements); 1069 } 1070 1071 } else if (value > 1) { 1072 value = (int) (value * linesToElements); 1073 1074 } else { 1075 value = (int) (value / linesToElements); 1076 } 1077 1078 value = (value > 0) ? value - 1 : value + 1; // since slider is one 1079 // off 1080 amSettingProperties = true; 1081 elementMagSlider.setValue(value); 1082 amSettingProperties = false; 1083 elementMagSliderChanged(false); 1084 } catch (Exception exc) { 1085 logException("Setting line magnification", exc); 1086 } 1087 // amSettingProperties = false; 1088 } 1089 1090 /** 1091 * Get the value of the line magnification slider. 1092 * 1093 * @return The magnification value for the line 1094 */ 1095 protected int getLineMagValue() { 1096 return getMagValue(lineMagSlider); 1097 } 1098 1099 /** 1100 * Get the value of the element magnification slider. 1101 * 1102 * @return The magnification value for the element 1103 */ 1104 protected int getElementMagValue() { 1105 return getMagValue(elementMagSlider); 1106 } 1107 1108 /** 1109 * Handle the absolute time selection changing 1110 */ 1111 @Override protected void absoluteTimesSelectionChanged() { 1112 if (!getDoAbsoluteTimes()) { 1113 return; 1114 } 1115 if (getIdv().getProperty("idv.chooser.addeimage.updateontimechange", 1116 true)) { 1117 setPropertiesState(getASelectedTime(), false); 1118 } 1119 } 1120 1121 /** 1122 * Set the relative and absolute extra components. 1123 */ 1124 @Override protected JPanel makeTimesPanel() { 1125 JPanel panel = 1126 super.makeTimesPanel(false, true, getIdv().getUseTimeDriver()); 1127 underTimelistPanel.add(BorderLayout.WEST, numImagesButton); 1128 underTimelistPanel.add(BorderLayout.CENTER, imageCountTextField); 1129 underTimelistPanel.add(BorderLayout.EAST, archiveDayBtn); 1130 return panel; 1131 } 1132 1133 /** 1134 * Associates the given JComponent with the PROP_ property identified by the 1135 * given propId 1136 * 1137 * @param propId 1138 * The property 1139 * @param comp 1140 * The gui component that allows the user to set the property 1141 * 1142 * @return Just returns the given comp 1143 */ 1144 protected JComponent addPropComp(String propId, JComponent comp) { 1145 Object oldComp = propToComps.get(propId); 1146 if (oldComp != null) { 1147 throw new IllegalStateException("Already have a component defined:" 1148 + propId); 1149 } 1150 propToComps.put(propId, comp); 1151 return comp; 1152 } 1153 1154 /** 1155 * Should we use the user supplied property 1156 * 1157 * @param propId 1158 * The property 1159 * 1160 * @return Should use the value from the advanced widget 1161 */ 1162 protected boolean usePropFromUser(String propId) { 1163 if (propToComps.get(propId) == null) { 1164 return false; 1165 } 1166 return true; 1167 } 1168 1169 /** 1170 * Get one of the selected times. 1171 * 1172 * @return One of the selected times. 1173 */ 1174 protected AreaDirectory getASelectedTime() { 1175 if (haveTimeSelected()) { 1176 List selected = getSelectedAbsoluteTimes(); 1177 if (selected.size() > 0) { 1178 AddeImageDescriptor aid = (AddeImageDescriptor) selected.get(0); 1179 if (aid != null) { 1180 return aid.getDirectory(); 1181 } 1182 } 1183 } 1184 return null; 1185 } 1186 1187 /** 1188 * Enable or disable the GUI widgets based on what has been selected. 1189 */ 1190 @Override protected void enableWidgets() { 1191 boolean descriptorState = ((getState() == STATE_CONNECTED) && canReadTimes()); 1192 1193 for (int i = 0; i < compsThatNeedDescriptor.size(); i++) { 1194 JComponent comp = (JComponent) compsThatNeedDescriptor.get(i); 1195 GuiUtils.enableTree(comp, descriptorState); 1196 } 1197 1198 boolean timesOk = timesOk(); 1199 if (propPanel != null) { 1200 GuiUtils.enableTree(propPanel, timesOk); 1201 } 1202 1203 // Require times to be selected 1204 GuiUtils.enableTree(loadButton, descriptorState && timesOk); 1205 1206 if (timesOk) { 1207 checkCenterEnabled(); 1208 } 1209 checkTimesLists(); 1210 1211 // TODO: This is temporary... absolute times on Windows makes the local 1212 // servers choke 1213 // Update: this works now, but leave it here as a reminder 1214 // boolean localWindowsServer = isLocalServer() && 1215 // System.getProperty("os.name").startsWith("Windows"); 1216 // setDoAbsoluteTimes(getDoAbsoluteTimes() && !localWindowsServer); 1217 1218 enableAbsoluteTimesList(getDoAbsoluteTimes() && descriptorState); 1219 1220 getRelativeTimesChooser().setEnabled( 1221 !getDoAbsoluteTimes() && descriptorState); 1222 1223 if (drivercbx != null) { 1224// logger.trace("set drivercbx={}", anyTimeDrivers() && descriptorState); 1225 drivercbx.setEnabled(anyTimeDrivers() && descriptorState); 1226 } 1227 revalidate(); 1228 } 1229 1230 /** 1231 * Check if we are using the lat/lon widget 1232 * 1233 * @return true if we are using the lat/lon widget 1234 */ 1235 protected boolean useLatLon() { 1236 return locationPanel.getVisibleIndex() == 0; 1237 } 1238 1239 /** 1240 * Enable or disable the center lat/lon and line/element widgets 1241 */ 1242 protected void checkCenterEnabled() { 1243 // NOT NOW 1244 if (true) { 1245 return; 1246 } 1247 1248 boolean usingLatLon = useLatLon(); 1249 1250 latLonWidget.getLatField().setEnabled(usingLatLon); 1251 latLonWidget.getLonField().setEnabled(usingLatLon); 1252 // centerLatLbl.setEnabled(usingLatLon); 1253 // centerLonLbl.setEnabled(usingLatLon); 1254 1255 centerLineFld.setEnabled(!usingLatLon); 1256 centerElementFld.setEnabled(!usingLatLon); 1257 // centerLineLbl.setEnabled( !usingLatLon); 1258 // centerElementLbl.setEnabled( !usingLatLon); 1259 1260 } 1261 1262 /** 1263 * Get the selected calibration unit. 1264 * 1265 * @return the selected calibration unit 1266 */ 1267 protected String getSelectedUnit() { 1268 if (unitComboBox==null || unitComboBox.getSelectedItem()==null) return ""; 1269 String selection = (String) ((TwoFacedObject) unitComboBox.getSelectedItem()).getId(); 1270 return selection; 1271 } 1272 1273 /** 1274 * Get the data type for this chooser 1275 * 1276 * @return the data type 1277 */ 1278 @Override public String getDataType() { 1279 return "IMAGE"; 1280 } 1281 1282 /** 1283 * Get a description of the currently selected dataset 1284 * 1285 * @return a description of the currently selected dataset 1286 * @deprecated use #getDatasetName() 1287 */ 1288 @Deprecated public String getDatasetDescription() { 1289 return getDatasetName(); 1290 } 1291 1292 /** 1293 * Read the set of image times available for the current server/group/type 1294 * This method is a wrapper, setting the wait cursor and wrapping the call 1295 * to {@link #readTimesInner(boolean)}; in a try/catch block 1296 */ 1297 @Override public void readTimes() { 1298 readTimes(false); 1299 } 1300 1301 public void readTimes(boolean forceAll) { 1302 1303 // Make sure there is a valid entry in the image count text field 1304 if (parseImageCount() < 0) return; 1305 1306 clearTimesList(); 1307 if (!canReadTimes()) { 1308 return; 1309 } 1310 Misc.run(new Runnable() { 1311 public void run() { 1312 updateStatus(); 1313 showWaitCursor(); 1314 try { 1315 readTimesInner(forceAll); 1316 checkSetNav(); 1317 } catch (Exception e) { 1318 handleConnectionError(e); 1319 } 1320 showNormalCursor(); 1321 updateStatus(); 1322 } 1323 }); 1324 } 1325 1326 /** 1327 * _more_ 1328 */ 1329 @Override public void doCancel() { 1330 readTimesTask = null; 1331 setState(STATE_UNCONNECTED); 1332 super.doCancel(); 1333 } 1334 1335 /** locking mutex */ 1336 private Object MUTEX = new Object(); 1337 1338 /** 1339 * Set the list of dates/times based on the image selection 1340 * 1341 */ 1342 protected void readTimesInner(boolean forceAll) { 1343 String descriptor = getDescriptor(); 1344 // String archivePosition = forceAll ? "all" : numTimes; 1345 String archivePosition = numTimes; 1346 String pos = (getDoAbsoluteTimes() || (archiveDay != null)) 1347 ? archivePosition 1348 : "0"; 1349 1350 StringBuffer addeCmdBuff = getGroupUrl(REQ_IMAGEDIR, getGroup()); 1351 String id = getSelectedStation(); 1352 if (id != null) { 1353 appendKeyValue(addeCmdBuff, PROP_ID, id); 1354 } 1355 appendKeyValue(addeCmdBuff, PROP_DESCR, descriptor); 1356 appendKeyValue(addeCmdBuff, PROP_POS, "" + pos); 1357 if (archiveDay != null) { 1358 appendKeyValue(addeCmdBuff, PROP_DAY, archiveDay); 1359 } 1360 String url = addeCmdBuff.toString(); 1361 readTimesTask = startTask(); 1362 updateStatus(); 1363 Object task = readTimesTask; 1364 try { 1365 AreaDirectoryList adir = new AreaDirectoryList(url); 1366 // Make sure no other loads are occurred 1367 boolean ok = stopTaskAndIsOk(task); 1368 if (!Misc.equals(readTimesTask, task) || !ok) { 1369 return; 1370 } 1371 readTimesTask = null; 1372 1373 synchronized (MUTEX) { 1374 // Array of AreaDirectory-s sorted by time 1375 AreaDirectory[][] dirs = adir.getSortedDirs(); 1376 int numImages = dirs.length; 1377 imageDescriptors = new Vector(); 1378 // TODO: Add a setBands method to AreaDirectory to replace bandtable 1379 bandTable = new Hashtable(numImages); 1380 int len = dirs[0].length; 1381 bandDirs = new Hashtable(len); 1382 for (int i = 0; i < len; i++) { 1383 AreaDirectory dir = dirs[0][i]; 1384 int ilen = dirs[0][i].getBands().length; 1385 for(int j = 0; j < ilen; j++){ 1386 int bindex = dirs[0][i].getBands()[j]; 1387 bandDirs.put(bindex, dir); 1388 } 1389 } 1390 lastAD = null; 1391 for (int i = 0; i < numImages; i++) { 1392 int bandIndex = 0; 1393 lastAD = (AreaDirectory) dirs[i][0]; 1394 int[] allBands = new int[MAX_BANDS]; 1395 Vector[] allCals = new Vector[MAX_BANDS]; 1396 for (int j = 0; j < dirs[i].length; j++) { 1397 int nbands = dirs[i][j].getNumberOfBands(); 1398 int[] abands = dirs[i][j].getBands(); 1399 Vector[] vb = dirs[i][j].getCalInfo(); 1400 for (int k = 0; k < nbands; k++) { 1401 allBands[bandIndex] = abands[k]; 1402 allCals[bandIndex++] = vb[k]; 1403 } 1404 } 1405 int[] bands = new int[bandIndex]; 1406 System.arraycopy(allBands, 0, bands, 0, bandIndex); 1407 Vector[] cals = new Vector[bandIndex]; 1408 System.arraycopy(allCals, 0, cals, 0, bandIndex); 1409 lastAD.setCalInfo(cals); 1410 bandTable.put(lastAD, bands); 1411 AddeImageDescriptor aid = new AddeImageDescriptor(lastAD, null); 1412 imageDescriptors.add(aid); 1413 } 1414 1415 Collections.sort(imageDescriptors); 1416 if (getDoAbsoluteTimes()) { 1417 setAbsoluteTimes(imageDescriptors); 1418 } 1419 // revalidate(); 1420 } 1421 setState(STATE_CONNECTED); 1422 } catch (McIDASException e) { 1423 logger.warn("Exception while reading times from server", e); 1424 stopTask(task); 1425 readTimesTask = null; 1426 handleConnectionError("\nError reading times", e); 1427 // you want this step because readTimes() will call updateStatus(), 1428 // and since we already have a server and dataset, all the user needs 1429 // to do is select an image type (descriptor). 1430 setState(STATE_CONNECTED); 1431 } 1432 } 1433 1434 /** 1435 * Set the selected times in the times list based on the input times 1436 * 1437 * @param times Input times. 1438 */ 1439 @Override protected void setSelectedTimes(DateTime[] times) { 1440 if ((times == null) || (times.length == 0)) { 1441 return; 1442 } 1443 DateTime[] imageTimes = new DateTime[times.length]; 1444 1445 if (imageDescriptors != null) { 1446 imageTimes = new DateTime[imageDescriptors.size()]; 1447 for (int idIdx = 0; idIdx < imageDescriptors.size(); idIdx++) { 1448 AddeImageDescriptor aid = (AddeImageDescriptor) imageDescriptors.get(idIdx); 1449 imageTimes[idIdx] = aid.getImageTime(); 1450 } 1451 } else { 1452 imageTimes = times; 1453 } 1454 if (imageTimes.length > 0) { 1455 try { 1456 Gridded1DSet imageSet = DateTime.makeTimeSet(imageTimes); 1457 int numTimes = times.length; 1458 double[][] timesValues = new double[1][numTimes]; 1459 for (int i = 0; i < times.length; i++) { 1460 timesValues[0][i] = times[i].getValue(imageSet.getSetUnits()[0]); 1461 } 1462 setSelectedAbsoluteTimes(imageSet.doubleToIndex(timesValues)); 1463 absoluteTimesSelectionChanged(); 1464 } catch (VisADException ve) { 1465 logException("Unable to set times from display", ve); 1466 } 1467 } 1468 } 1469 1470 /** 1471 * Set the center location portion of the request. If the input from the 1472 * widget is null, use the centerpoint from the image descriptor. 1473 * 1474 * @param aid Image descriptor for the image. 1475 */ 1476 protected void setCenterLocation(AddeImageDescriptor aid) { 1477 String latPoint = ""; 1478 String lonPoint = ""; 1479 if (aid != null) { 1480 AreaDirectory ad = aid.getDirectory(); 1481 latPoint = "" + ad.getCenterLatitude(); 1482 lonPoint = "" + ad.getCenterLongitude(); 1483 } 1484 if (!latPoint.trim().equals("")) { 1485 latLonWidget.setLat(latPoint); 1486 } 1487 if (!lonPoint.trim().equals("")) { 1488 latLonWidget.setLon(lonPoint); 1489 } 1490 } 1491 1492 /** 1493 * get the adde server grup type to use 1494 * 1495 * @return group type 1496 */ 1497 @Override protected String getGroupType() { 1498 return AddeServer.TYPE_IMAGE; 1499 } 1500 1501 /** 1502 * Does this selector have all of its state set to load in data 1503 * 1504 * @return Has the user chosen everything they need to choose to load data 1505 */ 1506 @Override protected boolean getGoodToGo() { 1507 // if(!super.getGoodToGo()) return false; 1508 if (getDoAbsoluteTimes()) { 1509 return getHaveAbsoluteTimesSelected(); 1510 } else { 1511 return canReadTimes() && (lastAD != null); 1512 } 1513 } 1514 1515 /** 1516 * Returns a list of the images to load or null if none have been selected. 1517 * 1518 * @return list get the list of image descriptors 1519 */ 1520 @Override public List getImageList() { 1521 if (!timesOk()) { 1522 return null; 1523 } 1524 List images = new ArrayList(); 1525 String defaultBand = getDefault(PROP_BAND, ALL); 1526 try { 1527 if (getDoRelativeTimes()) { 1528 AddeImageDescriptor firstDescriptor = (AddeImageDescriptor) imageDescriptors.get(0); 1529 AreaDirectory ad = firstDescriptor.getDirectory(); 1530 int[] bands = (int[]) bandTable.get(ad); 1531 bandInfos = makeBandInfos(ad, bands); 1532 int[] relativeTimesIndices = getRelativeTimeIndices(); 1533 for (int i = 0; i < relativeTimesIndices.length; i++) { 1534 AddeImageDescriptor aid = new AddeImageDescriptor(relativeTimesIndices[i], firstDescriptor); 1535 AddeImageInfo aii = makeImageInfo(aid.getDirectory(), true, relativeTimesIndices[i]); 1536 aii.setDebug(EntryStore.isAddeDebugEnabled(false)); 1537 if (aii.getBand() == null) aii.setBand(defaultBand); 1538 aid.setImageInfo(aii); 1539 aid.setSource(aii.getURLString()); 1540 images.add(aid); 1541 } 1542 } else { 1543 List selectedTimes = getSelectedAbsoluteTimes(); 1544 for (int i = 0; i < selectedTimes.size(); i++) { 1545 AddeImageDescriptor aid = new AddeImageDescriptor((AddeImageDescriptor) selectedTimes.get(i)); 1546 AddeImageInfo aii = makeImageInfo(aid.getDirectory(), false, i); 1547 aii.setDebug(EntryStore.isAddeDebugEnabled(false)); 1548 if (aii.getBand() == null) aii.setBand(defaultBand); 1549 aid.setImageInfo(aii); 1550 aid.setSource(aii.getURLString()); 1551 images.add(aid); 1552 } 1553 } 1554 } catch (Exception exc) { 1555 logException("Error occured", exc); 1556 return null; 1557 } 1558 return images; 1559 } 1560 1561 /** 1562 * Process the image defaults resources 1563 */ 1564 protected void initializeAddeDefaults() { 1565 resourceMaps = new ArrayList(); 1566 if (addeDefaults == null) { 1567 return; 1568 } 1569 for (int resourceIdx = 0; resourceIdx < addeDefaults.size(); resourceIdx++) { 1570 Element root = addeDefaults.getRoot(resourceIdx); 1571 if (root == null) { 1572 continue; 1573 } 1574 Hashtable resourceMap = new Hashtable(); 1575 resourceMaps.add(resourceMap); 1576 1577 XmlNodeList defaultNodes = XmlUtil.getElements(root, TAG_DEFAULT); 1578 for (int nodeIdx = 0; nodeIdx < defaultNodes.size(); nodeIdx++) { 1579 Element dfltNode = (Element) defaultNodes.item(nodeIdx); 1580 String pattern = XmlUtil.getAttribute(dfltNode, ATTR_PATTERN, 1581 (String) null); 1582 if (pattern == null) { 1583 pattern = XmlUtil.getAttribute(dfltNode, ATTR_NAME); 1584 } 1585 if (pattern != null) { 1586 pattern = pattern.toLowerCase(); 1587 } 1588 resourceMap.put(pattern, dfltNode); 1589 } 1590 } 1591 } 1592 1593 /** 1594 * Get the default value for a key 1595 * 1596 * @param property 1597 * property (key type) 1598 * @param dflt 1599 * default value 1600 * @return value for key or dflt if not found 1601 */ 1602 protected String getDefault(String property, String dflt) { 1603 if (resourceMaps == null) { 1604 initializeAddeDefaults(); 1605 } 1606 property = property.toLowerCase(); 1607 1608 String userDefault = null; 1609 String server = getServer(); 1610 String group = getGroup(); 1611 String descriptor = getDescriptor(); 1612 String[] keys = { userDefault, server + ":" + group + "/" + descriptor, 1613 group + "/" + descriptor, server + ":" + group + "/*", 1614 group + "/*", server + ":*/" + descriptor, "*/" + descriptor, 1615 descriptor, server + ":*/*", server, "*" }; 1616 1617 if (server != null) { 1618 if (PROP_USER.equals(property)) 1619 return getLastAddedUser(); 1620 if (PROP_PROJ.equals(property)) 1621 return getLastAddedProj(); 1622 } 1623 1624 for (int resourceIdx = 0; resourceIdx < resourceMaps.size(); resourceIdx++) { 1625 Hashtable resourceMap = (Hashtable) resourceMaps.get(resourceIdx); 1626 for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) { 1627 String key = keys[keyIdx]; 1628 if (key == null) { 1629 continue; 1630 } 1631 key = key.toLowerCase(); 1632 Element defaultNode = (Element)resourceMap.get(key); 1633 if (defaultNode == null) { 1634 continue; 1635 } 1636 String value = XmlUtil.getAttribute(defaultNode, property, (String)null); 1637 if (value == null) { 1638 continue; 1639 } 1640 if (value.equals(VALUE_DEFAULT)) { 1641 return dflt; 1642 } else { 1643 return value; 1644 } 1645 } 1646 } 1647 return dflt; 1648 } 1649 1650 /** 1651 * Get the image size string from the directory and defaults 1652 * 1653 * @param ad 1654 * image directory 1655 * @return request size 1656 */ 1657 protected String getSizeString(AreaDirectory ad) { 1658 String retString = MAX_SIZE + " " + MAX_SIZE; 1659 if (ad != null) { 1660 int x = ad.getElements(); 1661 int y = ad.getLines(); 1662 if ((x < MAX_SIZE) && (y < MAX_SIZE)) { 1663 retString = x + " " + y; 1664 } else if ((x >= MAX_SIZE) && (y >= MAX_SIZE)) { 1665 retString = MAX_SIZE + " " + MAX_SIZE; 1666 } else if ((x >= MAX_SIZE) && (y < MAX_SIZE)) { 1667 retString = MAX_SIZE + " " + y; 1668 } else if ((x < MAX_SIZE) && (y >= MAX_SIZE)) { 1669 retString = x + " " + MAX_SIZE; 1670 } 1671 } 1672 return retString; 1673 } 1674 1675 /** 1676 * Check for valid lat/lon values 1677 * 1678 * @return true if values are valid 1679 */ 1680 protected boolean checkForValidValues() { 1681 if (usePropFromUser(PROP_LOC)) { 1682 if (useLatLon()) { 1683 String msg = latLonWidget.isValidValues(); 1684 if ((msg != null) && (msg.length() > 0)) { 1685 LogUtil.userMessage(msg); 1686 return false; 1687 } 1688 } 1689 } 1690 return true; 1691 } 1692 1693 /** 1694 * Get the list of properties for the base URL 1695 * 1696 * @return list of properties 1697 */ 1698 protected String[] getBaseUrlProps() { 1699 return new String[] { PROP_DESCR, PROP_UNIT, PROP_SPAC, PROP_BAND, 1700 PROP_NAV, PROP_USER, PROP_PROJ, }; 1701 } 1702 1703 /** 1704 * A utility that creates the url argument line for the given set of 1705 * properties. 1706 * 1707 * @param props 1708 * The PROP_ properties to make the request string for 1709 * @param ad 1710 * The area directory. 1711 * 1712 * @return The adde request string 1713 */ 1714 protected String makeProps(String[] props, AreaDirectory ad) { 1715 StringBuffer buf = new StringBuffer(); 1716 for (int propIdx = 0; propIdx < props.length; propIdx++) { 1717 appendKeyValue(buf, props[propIdx], 1718 getPropValue(props[propIdx], ad)); 1719 } 1720 return buf.toString(); 1721 } 1722 1723 /** 1724 * Get the value for the given property. This can either be the value 1725 * supplied by the end user through the advanced GUI or is the default 1726 * 1727 * @param prop 1728 * The property 1729 * @param ad 1730 * The AreaDirectory 1731 * 1732 * @return The value of the property to use in the request string 1733 */ 1734 protected String getPropValue(String prop, AreaDirectory ad) { 1735 if (usePropFromUser(prop)) { 1736 return getUserPropValue(prop, ad); 1737 } 1738 1739 // Handle size specially because we really want to get the minimum of 1740 // the default and the ad size 1741 if (PROP_SIZE.equals(prop)) { 1742 int[] size = getSize(ad); 1743 return size[0] + " " + size[1]; 1744 } 1745 1746 return getDefault(prop, getDefaultPropValue(prop, ad, false)); 1747 } 1748 1749 /** 1750 * Get the user supplied property value for the adde request string 1751 * 1752 * @param prop 1753 * The property 1754 * @param ad 1755 * The AreaDirectory 1756 * 1757 * @return The value, supplied by the user, of the property to use in the 1758 * request string 1759 */ 1760 protected String getUserPropValue(String prop, AreaDirectory ad) { 1761 if (PROP_LATLON.equals(prop) && (latLonWidget != null)) { 1762 // apparently the ADDE server can't handle long numbers 1763 return Format.dfrac(latLonWidget.getLat(), 5) + " " 1764 + Format.dfrac(latLonWidget.getLon(), 5); 1765 } 1766 if (PROP_PLACE.equals(prop) && (placeLbl != null)) { 1767 return place; 1768 } 1769 1770 if (PROP_LINELE.equals(prop) && (centerLineFld != null)) { 1771 return centerLineFld.getText().trim() + " " 1772 + centerElementFld.getText().trim(); 1773 } 1774 1775 if (PROP_SIZE.equals(prop) && (numLinesFld != null)) { 1776 return numLinesFld.getText().trim() + " " 1777 + numElementsFld.getText().trim(); 1778 } 1779 if (PROP_MAG.equals(prop) && (lineMagSlider != null)) { 1780 return getLineMagValue() + " " + getElementMagValue(); 1781 } 1782 if (PROP_BAND.equals(prop) && (bandComboBox != null)) { 1783 1784 Object selected = bandComboBox.getSelectedItem(); 1785 if (selected != null) { 1786 if (selected.equals(ALLBANDS)) { 1787 return ALLBANDS.toString(); 1788 } else { 1789 return "" + ((BandInfo) selected).getBandNumber(); 1790 } 1791 } 1792 } 1793 if (PROP_UNIT.equals(prop)) { 1794 return getSelectedUnit(); 1795 } 1796 if (PROP_NAV.equals(prop)) { 1797 return TwoFacedObject.getIdString(navComboBox.getSelectedItem()); 1798 } 1799 1800 if (PROP_USER.equals(prop)) 1801 return getLastAddedUser(); 1802 if (PROP_PROJ.equals(prop)) 1803 return getLastAddedProj(); 1804 1805 return null; 1806 } 1807 1808 /** 1809 * Get the default property value for the adde request string 1810 * 1811 * @param prop 1812 * The property 1813 * @param ad 1814 * The AreaDirectory 1815 * @param forDisplay 1816 * Is this to display to the user in the gui 1817 * 1818 * @return The default of the property to use in the request string 1819 */ 1820 protected String getDefaultPropValue(String prop, AreaDirectory ad, 1821 boolean forDisplay) { 1822 if (PROP_USER.equals(prop)) { 1823 return DEFAULT_USER; 1824 } 1825 if (PROP_USER.equals(prop)) { 1826 return PLACE_CENTER; 1827 } 1828 if (PROP_PROJ.equals(prop)) { 1829 return DEFAULT_PROJ; 1830 } 1831 if (PROP_DESCR.equals(prop)) { 1832 return getDescriptor(); 1833 } 1834 if (PROP_VERSION.equals(prop)) { 1835 return DEFAULT_VERSION; 1836 } 1837 if (PROP_COMPRESS.equals(prop)) { 1838 return "gzip"; 1839 } 1840 if (PROP_PORT.equals(prop)) { 1841 return DEFAULT_PORT; 1842 } 1843 if (PROP_DEBUG.equals(prop)) { 1844// return DEFAULT_DEBUG; 1845 Boolean.toString(EntryStore.isAddeDebugEnabled(false)); 1846 } 1847 if (PROP_SIZE.equals(prop)) { 1848 if (ad != null) { 1849 return ad.getLines() + " " + ad.getElements(); 1850 } 1851 return MAX_SIZE + " " + MAX_SIZE; 1852 } 1853 if (PROP_MAG.equals(prop)) { 1854 return "1 1"; 1855 } 1856 // if (prop.equals(PROP_LOC) || prop.equals(PROP_LINELE)) { 1857 if (PROP_MAG.equals(prop)) { 1858 if (ad == null) { 1859 return "0 0"; 1860 } 1861 return ad.getLines() / 2 + " " + ad.getElements() / 2; 1862 } 1863 // if (prop.equals(PROP_LATLON)) { 1864 if (PROP_LOC.equals(prop) || PROP_LATLON.equals(prop)) { 1865 if (ad == null) { 1866 return "0 0"; 1867 } 1868 return ad.getCenterLatitude() + " " + ad.getCenterLongitude(); 1869 } 1870 if (PROP_BAND.equals(prop)) { 1871 if (bandTable==null) return ""; 1872 if (forDisplay) { 1873 return getBandName(ad, ((int[]) bandTable.get(ad))[0]); 1874 } 1875 return "" + ((int[]) bandTable.get(ad))[0]; 1876 } 1877 if (PROP_SPAC.equals(prop)) { 1878 return getSelectedUnit().equalsIgnoreCase("BRIT") ? "1" : "4"; 1879 } 1880 if (PROP_UNIT.equals(prop)) { 1881 return "X"; 1882 } 1883 if (PROP_NAV.equals(prop)) { 1884 return "X"; 1885 } 1886 return ""; 1887 } 1888 1889 /** 1890 * Set the properties on the AddeImageInfo from the list of properties 1891 * 1892 * @param aii 1893 * The AddeImageInfo 1894 * @param props 1895 * list of props to set 1896 * @param ad 1897 * The AreaDirectory 1898 */ 1899 protected void setImageInfoProps(AddeImageInfo aii, String[] props, AreaDirectory ad) { 1900 for (int i = 0; i < props.length; i++) { 1901 String prop = props[i]; 1902 String value = getPropValue(prop, ad); 1903 if (prop.equals(PROP_USER)) { 1904 aii.setUser(value); 1905 } else if (prop.equals(PROP_PROJ)) { 1906 aii.setProject(Integer.parseInt(value)); 1907 } else if (prop.equals(PROP_DESCR)) { 1908 aii.setDescriptor(value); 1909 } else if (prop.equals(PROP_VERSION)) { 1910 aii.setVersion(value); 1911 } else if (prop.equals(PROP_COMPRESS)) { 1912 int compVal = AddeURL.GZIP; 1913 if (value.equals("none") || value.equals("1")) { 1914 compVal = AddeURL.NO_COMPRESS; 1915 } else if (value.equals("compress") || value.equals("2") || value.equals("true")) { 1916 compVal = AddeURL.COMPRESS; 1917 } 1918 aii.setCompression(compVal); 1919 } else if (prop.equals(PROP_PORT)) { 1920 aii.setPort(Integer.parseInt(value)); 1921 } else if (prop.equals(PROP_DEBUG)) { 1922// aii.setDebug(Boolean.getBoolean(value)); 1923 aii.setDebug(EntryStore.isAddeDebugEnabled(false)); 1924 } else if (prop.equals(PROP_SPAC)) { 1925 aii.setSpacing(Integer.parseInt(value)); 1926 } else if (prop.equals(PROP_UNIT)) { 1927 if (value.equals(ALLUNITS.getId())) { 1928 value = getDefault(prop, getDefaultPropValue(prop, ad, false)); 1929 } 1930 aii.setUnit(value); 1931 } else if (prop.equals(PROP_BAND)) { 1932 if (value.equals(ALLBANDS.toString())) { 1933 value = getDefault(prop, getDefaultPropValue(prop, ad, false)); 1934 } 1935 aii.setBand(value); 1936 } else if (prop.equals(PROP_NAV)) { 1937 aii.setNavType(value); 1938 } else if (prop.equals(PROP_ID)) { 1939 aii.setId(value); 1940 } 1941 } 1942 } 1943 1944 /** 1945 * Get the name of the selected band 1946 * 1947 * @return the name of the band 1948 */ 1949 public String getSelectedBandName() { 1950 return getBandName(propertiesAD, getSelectedBand()); 1951 } 1952 1953 /** 1954 * Clear the properties widgets 1955 */ 1956 protected void clearPropertiesWidgets() { 1957 if (latLonWidget != null) { 1958 latLonWidget.getLatField().setText(""); 1959 latLonWidget.getLonField().setText(""); 1960 } 1961 if (centerLineFld != null) { 1962 centerLineFld.setText(""); 1963 centerElementFld.setText(""); 1964 } 1965 if (numLinesFld != null) { 1966 if (sizeLbl != null) { 1967 sizeLbl.setText(""); 1968 } 1969 numLinesFld.setText(""); 1970 numElementsFld.setText(""); 1971 } 1972 if (unitComboBox != null) { 1973 GuiUtils.setListData(unitComboBox, new Vector()); 1974 } 1975 if (bandComboBox != null) { 1976 GuiUtils.setListData(bandComboBox, new Vector()); 1977 } 1978 1979 setMagSliders(DEFAULT_MAG, DEFAULT_MAG); 1980 1981 if (placeLbl != null) { 1982 changePlace(PLACE_CENTER); 1983 } 1984 1985 if (navComboBox != null) { 1986 checkSetNav(); 1987// navComboBox.setSelectedIndex(0); 1988 } 1989 baseNumLines = 0.0; 1990 baseNumElements = 0.0; 1991 } 1992 1993 /** 1994 * Set the widgets with the state from the given AreaDirectory 1995 * 1996 * @param ad 1997 * AreaDirectory for the image 1998 */ 1999 protected void setPropertiesState(AreaDirectory ad) { 2000 setPropertiesState(ad, false); 2001 } 2002 2003 /** 2004 * _more_ 2005 * 2006 * @param ad 2007 * _more_ 2008 * 2009 * @return _more_ 2010 */ 2011 protected int[] getSize(AreaDirectory ad) { 2012 baseNumLines = ad.getLines(); 2013 baseNumElements = ad.getElements(); 2014 2015 String sizeDefault = getDefault(PROP_SIZE, (String) null); 2016 List toks = ((sizeDefault != null) ? StringUtil.split(sizeDefault, " ", 2017 true, true) : null); 2018 if ((toks == null) || (toks.size() == 0)) { 2019 return new int[] { (int) baseNumLines, (int) baseNumElements }; 2020 } else { 2021 String lines = "" + toks.get(0); 2022 if (lines.equalsIgnoreCase(ALL)) { 2023 lines = "" + (int) baseNumLines; 2024 } 2025 int numLines = new Integer(lines.trim()).intValue(); 2026 2027 String elems = (toks.size() > 1) ? "" + toks.get(1) : "" 2028 + (int) baseNumElements; 2029 if (elems.equalsIgnoreCase(ALL)) { 2030 elems = "" + baseNumElements; 2031 } 2032 int numElements = new Integer(elems.trim()).intValue(); 2033 return new int[] { (int) Math.min(numLines, baseNumLines), 2034 (int) Math.min(numElements, baseNumElements) }; 2035 } 2036 2037 } 2038 2039 /** 2040 * Set the widgets with the state from the given AreaDirectory 2041 * 2042 * @param ad 2043 * AreaDirectory for the image 2044 * @param force 2045 * force an update regardless of the previous invocation 2046 */ 2047 protected void setPropertiesState(AreaDirectory ad, boolean force) { 2048 if (amSettingProperties) 2049 return; 2050 2051 prevPropertiesAD = propertiesAD; 2052 propertiesAD = ad; 2053 if (!force && checkPropertiesEqual(prevPropertiesAD, propertiesAD)) 2054 return; 2055 2056 amSettingProperties = true; 2057 2058 if (ad == null) { 2059 clearPropertiesWidgets(); 2060 amSettingProperties = false; 2061 return; 2062 } 2063 2064 String[] propArray = getAdvancedProps(); 2065 2066 if (numLinesFld != null) { 2067 int[] size = getSize(ad); 2068 numLinesFld.setText("" + size[0]); 2069 numElementsFld.setText("" + size[1]); 2070 if (sizeLbl != null) { 2071 String label = " Raw size: " + ad.getLines() + " X " 2072 + ad.getElements(); 2073 sizeLbl.setText(label); 2074 } 2075 } 2076 if (latLonWidget != null) { 2077 latLonWidget.getLatField().setText("" + ad.getCenterLatitude()); 2078 latLonWidget.getLonField().setText("" + ad.getCenterLongitude()); 2079 } 2080 if (centerLineFld != null) { 2081 centerLineFld.setText("" + ad.getLines() / 2); 2082 centerElementFld.setText("" + ad.getElements() / 2); 2083 } 2084 2085 List<BandInfo> bandList = null; 2086 int[] bands = (int[]) bandTable.get(ad); 2087 if (bands != null) 2088 bandList = makeBandInfos(ad, bands); 2089 bandInfos = bandList; 2090 2091 if (bandComboBox != null) { 2092 List comboList = bandList; 2093 if (bandList.size() > 1) { 2094 comboList = new ArrayList(); 2095 comboList.addAll(bandList); 2096 comboList.add(ALLBANDS); 2097 } 2098 GuiUtils.setListData(bandComboBox, comboList); 2099 } 2100 2101 setAvailableUnits(ad, getSelectedBand()); 2102 2103 for (int propIdx = 0; propIdx < propArray.length; propIdx++) { 2104 String prop = propArray[propIdx]; 2105 String value = getDefault(prop, getDefaultPropValue(prop, ad, false)); 2106 if (value == null) 2107 value = ""; 2108 2109 value = value.trim(); 2110 if (prop.equals(PROP_LOC)) { 2111 String key = getDefault(PROP_KEY, PROP_LATLON); 2112 2113 boolean usingLineElement = key.equals(PROP_LINELE); 2114 if (usingLineElement) { 2115 locationPanel.show(1); 2116 } else { 2117 locationPanel.show(0); 2118 } 2119 if (usingLineElement) { 2120 value = getDefault(PROP_LOC, getDefaultPropValue( 2121 PROP_LINELE, ad, false)); 2122 } else { 2123 value = getDefault(PROP_LOC, getDefaultPropValue( 2124 PROP_LATLON, ad, false)); 2125 } 2126 String[] pair = getPair(value); 2127 if (pair != null) { 2128 if (usingLineElement) { 2129 centerLineFld.setText(pair[0]); 2130 centerElementFld.setText(pair[1]); 2131 } else { 2132 latLonWidget.setLat(pair[0]); 2133 latLonWidget.setLon(pair[1]); 2134 } 2135 } 2136 } else if (prop.equals(PROP_BAND)) { 2137 if (value.equalsIgnoreCase((String) ALLBANDS.getId())) { 2138 bandComboBox.setSelectedItem(ALLBANDS); 2139 } else { 2140 int bandNum = 0; 2141 try { 2142 bandNum = Integer.parseInt(value); 2143 } catch (NumberFormatException nfe) { 2144 } 2145 int index = BandInfo.findIndexByNumber(bandNum, bandList); 2146 if (index != -1) { 2147 bandComboBox.setSelectedIndex(index); 2148 } 2149 } 2150 } else if (prop.equals(PROP_PLACE)) { 2151 changePlace(value); 2152 } else if (prop.equals(PROP_MAG)) { 2153 String[] pair = getPair(value); 2154 if (pair != null) { 2155 setMagSliders(new Integer(pair[0]).intValue(), new Integer( 2156 pair[1]).intValue()); 2157 } else { 2158 setMagSliders(DEFAULT_MAG, DEFAULT_MAG); 2159 } 2160 } else if (prop.equals(PROP_NAV)) { 2161 if (navComboBox != null) { 2162 navComboBox.setSelectedIndex((value 2163 .equalsIgnoreCase("LALO") ? 1 : 0)); 2164 } 2165 checkSetNav(); 2166 } 2167 } 2168 amSettingProperties = false; 2169 2170 } 2171 2172 /** 2173 * Set the mag slider values 2174 * 2175 * @param lineValue 2176 * the line value 2177 * @param elementValue 2178 * the element value 2179 */ 2180 protected void setMagSliders(int lineValue, int elementValue) { 2181 if (lineMagSlider != null) { 2182 if (lineValue > 0) { 2183 lineValue--; 2184 } else if (lineValue < 0) { 2185 lineValue++; 2186 } 2187 if (elementValue > 0) { 2188 elementValue--; 2189 } else if (elementValue < 0) { 2190 elementValue++; 2191 } 2192 2193 lineMagSlider.setValue(lineValue); 2194 elementMagSlider.setValue(elementValue); 2195 lineMagLbl.setText(StringUtil.padLeft("" + getLineMagValue(), 4)); 2196 elementMagLbl.setText(StringUtil.padLeft("" + getElementMagValue(), 2197 4)); 2198 linesToElements = Math.abs(lineValue / (double) elementValue); 2199 if (Double.isNaN(linesToElements)) { 2200 linesToElements = 1.0; 2201 } 2202 } 2203 } 2204 2205 /** 2206 * Get the value of the given magnification slider. 2207 * 2208 * @param slider 2209 * The slider to get the value from 2210 * @return The magnification value 2211 */ 2212 protected int getMagValue(JSlider slider) { 2213 // Value is [-SLIDER_MAX,SLIDER_MAX]. We change 0 and -1 to 1 2214 int value = slider.getValue(); 2215 if (value >= 0) { 2216 return value + 1; 2217 } 2218 return value - 1; 2219 } 2220 2221 /** 2222 * Get a pair of properties 2223 * 2224 * @param v 2225 * a space separated string 2226 * 2227 * @return an array of the two strings 2228 */ 2229 protected String[] getPair(String v) { 2230 if (v == null) { 2231 return null; 2232 } 2233 v = v.trim(); 2234 List toks = StringUtil.split(v, " ", true, true); 2235 if ((toks == null) || (toks.size() == 0)) { 2236 return null; 2237 } 2238 String tok1 = toks.get(0).toString(); 2239 return new String[] { tok1, 2240 ((toks.size() > 1) ? toks.get(1).toString() : tok1) }; 2241 2242 } 2243 2244 /** 2245 * Get the selected band from the advanced chooser 2246 * 2247 * @return selected band number 2248 */ 2249 protected int getSelectedBand() { 2250 2251 Object bi = (bandComboBox == null) ? null : bandComboBox 2252 .getSelectedItem(); 2253 if ((bi == null) || bi.equals(ALLBANDS)) { 2254 return 0; 2255 } 2256 return ((BandInfo) bi).getBandNumber(); 2257 } 2258 2259 /** 2260 * Translate a place name into a human readable form 2261 * 2262 * @param place 2263 * raw name 2264 * 2265 * @return human readable name 2266 */ 2267 protected String translatePlace(String place) { 2268 place = place.toUpperCase(); 2269 if (place.equals(PLACE_ULEFT)) { 2270 return "Upper left"; 2271 } 2272 if (place.equals(PLACE_LLEFT)) { 2273 return "Lower left"; 2274 } 2275 if (place.equals(PLACE_URIGHT)) { 2276 return "Upper right"; 2277 } 2278 if (place.equals(PLACE_LRIGHT)) { 2279 return "Lower right"; 2280 } 2281 if (place.equals(PLACE_CENTER)) { 2282 return "Center"; 2283 } 2284 return place; 2285 } 2286 2287 /** 2288 * Get the band name for a particular area 2289 * 2290 * @param ad 2291 * AreaDirectory 2292 * @param band 2293 * band number 2294 * 2295 * @return name of the band 2296 */ 2297 protected String getBandName(AreaDirectory ad, int band) { 2298 // if (band== 0) return ALLBANDS.toString(); 2299 2300 if (useSatBandInfo) { 2301 if (satBandInfo == null) { 2302 return "Band: " + band; 2303 } 2304 String[] descrs = satBandInfo.getBandDescr(ad.getSensorID(), ad 2305 .getSourceType()); 2306 if (descrs != null) { 2307 if ((band >= 0) && (band < descrs.length)) { 2308 return descrs[band]; 2309 } 2310 } 2311 return "Band: " + band; 2312 } 2313 2314 if (sensorToBandToName == null) { 2315 return "Band: " + band; 2316 } 2317 Hashtable bandToName = (Hashtable) sensorToBandToName.get(new Integer( 2318 ad.getSensorID())); 2319 String name = null; 2320 Integer bandInteger = new Integer(band); 2321 2322 if (bandToName != null) { 2323 name = (String) bandToName.get(bandInteger); 2324 } 2325 if (name == null) { 2326 name = "Band: " + band; 2327 } 2328 /* 2329 * else { name = band + " - " + name.trim(); } 2330 */ 2331 return name; 2332 } 2333 2334 /** 2335 * Set the available units in the unit selector 2336 * 2337 * @param ad 2338 * AreaDirectory for the image 2339 * @param band 2340 * band to use for units 2341 */ 2342 protected void setAvailableUnits(AreaDirectory ad, int band) { 2343 List l = getAvailableUnits(ad, band); 2344 l.add(ALLUNITS); 2345 GuiUtils.setListData(unitComboBox, l); 2346 TwoFacedObject tfo = null; 2347 if ((bandComboBox != null) && (getSelectedBand() == 0)) { 2348 tfo = ALLUNITS; 2349 } else { 2350 String preferredUnit = getDefault(PROP_UNIT, "BRIT"); 2351 tfo = TwoFacedObject.findId(preferredUnit, l); 2352 } 2353 if (tfo != null) { 2354 unitComboBox.setSelectedItem(tfo); 2355 } 2356 } 2357 2358 /** 2359 * Set the available units in the unit selector 2360 * 2361 * @param ad 2362 * AreaDirectory for the image 2363 * @param band 2364 * band to use for units 2365 * 2366 * @return List of available units 2367 */ 2368 protected List<TwoFacedObject> getAvailableUnits(AreaDirectory ad, int band) { 2369 // get Vector array of Calibration types. Layout is 2370 // v[i] = band[i] and for each band, it is a vector of 2371 // strings of calibration names and descriptions 2372 // n = name, n+1 = desc. 2373 // for radar, we only have one band 2374 if (ad == null) { 2375 return new ArrayList<>(); 2376 } 2377 int[] bands = (int[]) bandTable.get(ad); 2378 int index = (bands == null) ? 0 : Arrays.binarySearch(bands, band); 2379 if (index < 0) index = 0; 2380 Vector<TwoFacedObject> l = new Vector<>(); 2381 Vector v = ad.getCalInfo()[index]; 2382 TwoFacedObject tfo = null; 2383 int preferredUnitIndex = 0; 2384 String preferredUnit = getDefault(PROP_UNIT, "BRIT"); 2385 if ((v != null) && (v.size() / 2 > 0)) { 2386 for (int i = 0; i < v.size() / 2; i++) { 2387 String name = (String) v.get(2 * i); 2388 String desc = (String) v.get(2 * i + 1); 2389 desc = StringUtil.camelCase(desc); 2390 tfo = new TwoFacedObject(desc, name); 2391 l.add(tfo); 2392 if (name.equalsIgnoreCase(preferredUnit)) { 2393 preferredUnitIndex = i; 2394 } 2395 } 2396 } else { 2397 l.add(new TwoFacedObject("Raw Value", "RAW")); 2398 } 2399 return l; 2400 } 2401 2402 /** 2403 * Get the band name information from the server 2404 */ 2405 protected void readSatBands() { 2406 satBandInfo = null; 2407 sensorToBandToName = null; 2408 List lines = null; 2409 try { 2410 StringBuffer buff = getUrl(REQ_TEXT); 2411 appendKeyValue(buff, PROP_FILE, FILE_SATBAND); 2412 lines = readTextLines(buff.toString()); 2413 if (lines == null) { 2414 return; 2415 } 2416 if (useSatBandInfo) { 2417 satBandInfo = new AddeSatBands(StringUtil.listToStringArray(lines)); 2418 return; 2419 } 2420 } catch (Exception e) { 2421 return; 2422 } 2423 2424 if (lines == null) { 2425 return; 2426 } 2427 2428 sensorToBandToName = new Hashtable(); 2429 2430 for (int i = 0; i < lines.size(); i++) { 2431 if (!lines.get(i).toString().startsWith("Sat")) { 2432 continue; 2433 } 2434 List satIds = StringUtil.split(lines.get(i).toString(), " ", true, 2435 true); 2436 satIds.remove(0); 2437 Hashtable bandToName = new Hashtable(); 2438 for (int j = i + 1; j < lines.size(); j++, i++) { 2439 String line = lines.get(i).toString(); 2440 line = line.trim(); 2441 if (line.startsWith("EndSat")) { 2442 break; 2443 } 2444 2445 int idx = line.indexOf(" "); 2446 if (idx < 0) { 2447 continue; 2448 } 2449 String bandTok = line.substring(0, idx); 2450 try { 2451 bandToName.put(Integer.decode(bandTok.trim()), line 2452 .substring(idx).trim()); 2453 } catch (NumberFormatException nfe) { 2454 } 2455 } 2456 for (int j = 0; j < satIds.size(); j++) { 2457 Integer sensorId = new Integer(satIds.get(j).toString()); 2458 sensorToBandToName.put(sensorId, bandToName); 2459 } 2460 } 2461 } 2462 2463 /** 2464 * Make an AddeImageInfo from a URL and an AreaDirectory 2465 * 2466 * @param dir 2467 * AreaDirectory 2468 * @param isRelative 2469 * true if is relative 2470 * @param num 2471 * number (for relative images) 2472 * 2473 * @return corresponding AddeImageInfo 2474 */ 2475 protected AddeImageInfo makeImageInfo(AreaDirectory dir, 2476 boolean isRelative, int num) { 2477 AddeImageInfo info = new AddeImageInfo(getAddeServer().getName(), 2478 AddeImageInfo.REQ_IMAGEDATA, getGroup(), getDescriptor()); 2479 if (isRelative) { 2480 info.setDatasetPosition((num == 0) ? 0 : -num); 2481 } else { 2482 info.setStartDate(dir.getNominalTime()); 2483 } 2484 setImageInfoProps(info, getMiscKeyProps(), dir); 2485 setImageInfoProps(info, getBaseUrlProps(), dir); 2486 2487 String locKey = getDefault(PROP_KEY, PROP_LINELE); 2488 String locValue = null; 2489 if (usePropFromUser(PROP_LOC)) { 2490 if (useLatLon()) { 2491 locKey = PROP_LATLON; 2492 locValue = getUserPropValue(PROP_LATLON, dir); 2493 } else { 2494 locKey = PROP_LINELE; 2495 locValue = getUserPropValue(PROP_LINELE, dir); 2496 } 2497 } else { 2498 locValue = getPropValue(PROP_LOC, dir); 2499 } 2500 info.setLocateKey(locKey); 2501 info.setLocateValue(locValue); 2502 2503 String placeKey = getPropValue(PROP_PLACE, dir); 2504 info.setPlaceValue(placeKey); 2505 2506 String magKey = getPropValue(PROP_MAG, dir); 2507 int lmag = 1; 2508 int emag = 1; 2509 StringTokenizer tok = new StringTokenizer(magKey); 2510 lmag = (int) Misc.parseNumber((String) tok.nextElement()); 2511 if (tok.hasMoreTokens()) { 2512 emag = (int) Misc.parseNumber((String) tok.nextElement()); 2513 } else { 2514 emag = lmag; 2515 } 2516 info.setLineMag(lmag); 2517 info.setElementMag(emag); 2518 2519 int lines = dir.getLines(); 2520 int elems = dir.getElements(); 2521 String sizeKey = getPropValue(PROP_SIZE, dir); 2522 tok = new StringTokenizer(sizeKey); 2523 String size = (String) tok.nextElement(); 2524 if (!size.equalsIgnoreCase("all")) { 2525 lines = (int) Misc.parseNumber(size); 2526 if (tok.hasMoreTokens()) { 2527 elems = (int) Misc.parseNumber((String) tok.nextElement()); 2528 } else { 2529 elems = lines; 2530 } 2531 } 2532 info.setLines(lines); 2533 info.setElements(elems); 2534 /* 2535 * System.out.println("url = " + info.getURLString().toLowerCase() + 2536 * "\n"); 2537 */ 2538 return info; 2539 } 2540 2541 /** 2542 * Check to see if the two Area directories are equal 2543 * 2544 * @param ad1 2545 * first AD (may be null) 2546 * @param ad2 2547 * second AD (may be null) 2548 * 2549 * @return true if they are equal 2550 */ 2551 protected boolean checkPropertiesEqual(AreaDirectory ad1, AreaDirectory ad2) { 2552 if (ad1 == null) { 2553 return false; 2554 } 2555 if (ad2 == null) { 2556 return false; 2557 } 2558 return Misc.equals(ad1, ad2) 2559 || ((ad1.getLines() == ad2.getLines()) 2560 && (ad1.getElements() == ad2.getElements()) && Arrays 2561 .equals(ad1.getBands(), ad2.getBands())); 2562 } 2563 2564 /** 2565 * Get a description of the properties 2566 * 2567 * @return a description 2568 */ 2569 protected String getPropertiesDescription() { 2570 StringBuffer buf = new StringBuffer(); 2571 String[] propArray = getAdvancedProps(); 2572 List list = Misc.toList(propArray); 2573 if (list.contains(PROP_BAND)) { 2574 buf.append(getSelectedBandName()); 2575 buf.append(", "); 2576 } 2577 if (list.contains(PROP_SIZE)) { 2578 buf.append("Size: "); 2579 String sizeKey = getUserPropValue(PROP_SIZE, propertiesAD); 2580 StringTokenizer tok = new StringTokenizer(sizeKey); 2581 if (tok.hasMoreTokens()) { 2582 String size = ((String) tok.nextElement()).trim(); 2583 buf.append(size); 2584 buf.append("x"); 2585 if (!size.equalsIgnoreCase("all")) { 2586 if (tok.hasMoreTokens()) { 2587 buf.append(((String) tok.nextElement()).trim()); 2588 } else { 2589 buf.append(size); 2590 } 2591 } 2592 } 2593 } 2594 return buf.toString(); 2595 } 2596 2597 /** 2598 * Show the given error to the user. If it was an ADDE exception that was 2599 * a bad server error then print out a nice message. 2600 * 2601 * <p>Overridden in McIDAS-V to work with ADDE {@literal "archive"} 2602 * servers (servers that require a {@literal "DAY="} parameter).</p> 2603 * 2604 * @param e Exception to be handled. Cannot be {@code null}. 2605 */ 2606 @Override protected void handleConnectionError(Exception e) { 2607 handleConnectionError("", e); 2608 } 2609 2610 /** 2611 * Show the given error to the user. If it was an ADDE exception that was 2612 * a bad server error then print out a nice message. 2613 * 2614 * <p>Overridden in McIDAS-V to work with ADDE {@literal "archive"} 2615 * servers (servers that require a {@literal "DAY="} parameter).</p> 2616 * 2617 * @param details Details about the context of {@code e}. {@code null} 2618 * will be treated as an empty {@code String}. 2619 * @param e Exception to be handled. Cannot be {@code null}. 2620 */ 2621 @Override protected void handleConnectionError(String details, Exception e) { 2622 if ((e != null) && (e.getMessage() != null)) { 2623 Throwable cause = e.getCause(); 2624 if (cause.getMessage() != null) { 2625 String msg = cause.getMessage().toLowerCase(); 2626 if ((cause instanceof AddeURLException) && msg.contains("must be used with archived datasets")) { 2627 getArchiveDay(); 2628 return; 2629 } 2630 } 2631 } 2632 super.handleConnectionError(details, e); 2633 } 2634 2635 /** 2636 * Get the list of bands for the images 2637 * 2638 * @param ad 2639 * AreaDirectory 2640 * @param bands 2641 * list of bands 2642 * @return list of BandInfos for the selected images 2643 */ 2644 protected List<BandInfo> makeBandInfos(AreaDirectory ad, int[] bands) { 2645 // readSatBands(); 2646 List<BandInfo> l = new ArrayList<>(); 2647 if (ad != null) { 2648 if (bands != null) { 2649 for (int i = 0; i < bands.length; i++) { 2650 int band = bands[i]; 2651 if (band > 0) { 2652 BandInfo bi = new BandInfo(ad.getSensorID(), band); 2653 bi.setBandDescription(getBandName(ad, band)); 2654 bi.setCalibrationUnits(getAvailableUnits(ad, band)); 2655 bi.setPreferredUnit(getDefault(PROP_UNIT, "BRIT")); 2656 l.add(bi); 2657 } 2658 } 2659 } 2660 } 2661 return l; 2662 } 2663 2664 /** 2665 * Get the pregenerated bandInfos 2666 */ 2667 protected List<BandInfo> getBandInfos() { 2668 return bandInfos; 2669 } 2670 2671 /** 2672 * Get the list of BandInfos for the current selected images 2673 * 2674 * @return list of BandInfos 2675 */ 2676 public List<BandInfo> getSelectedBandInfos() { 2677 // update the BandInfo list based on what has been chosen 2678 List selectedBandInfos = new ArrayList<>(); 2679 List selectedUnits = null; 2680 if (unitComboBox != null) { 2681 TwoFacedObject tfo = (TwoFacedObject) unitComboBox.getSelectedItem(); 2682 if (!(tfo.equals(ALLUNITS))) { // specific unit requested 2683 selectedUnits = new ArrayList<>(); 2684 selectedUnits.add(tfo); 2685 } 2686 } 2687 if (getSelectedBand() == 0) { // All bands selected 2688 if (selectedUnits != null) { 2689 for (Iterator iter = bandInfos.iterator(); iter.hasNext();) { 2690 BandInfo newBI = new BandInfo((BandInfo) iter.next()); 2691 newBI.setCalibrationUnits(selectedUnits); 2692 newBI.setPreferredUnit((String) ((TwoFacedObject) selectedUnits.get(0)).getId()); 2693 selectedBandInfos.add(newBI); 2694 } 2695 } else { // else All Bands, AllUnits 2696 selectedBandInfos = bandInfos; 2697 } 2698 } else { // not All selected; 2699 int index = BandInfo.findIndexByNumber(getSelectedBand(), bandInfos); 2700 BandInfo selectedBandInfo = null; 2701 if (index != -1) { 2702 selectedBandInfo = bandInfos.get(index); 2703 } 2704 if (selectedBandInfo != null) { 2705 if (selectedUnits != null) { 2706 BandInfo newBI = new BandInfo(selectedBandInfo); 2707 newBI.setCalibrationUnits(selectedUnits); 2708 newBI.setPreferredUnit((String) ((TwoFacedObject) selectedUnits.get(0)).getId()); 2709 selectedBandInfos.add(newBI); 2710 } else { 2711 selectedBandInfos.add(selectedBandInfo); 2712 } 2713 } 2714 } 2715 return selectedBandInfos; 2716 } 2717 2718 /** 2719 * Get the id for the default display type 2720 * 2721 * @return the display id 2722 */ 2723 @Override protected String getDefaultDisplayType() { 2724 return "imagedisplay"; 2725 } 2726 2727 /** 2728 * User said go, we go. Simply get the list of images from the imageChooser 2729 * and create the ADDE.IMAGE DataSource 2730 * 2731 */ 2732 @Override public void doLoadInThread() { 2733 if (!checkForValidValues()) { 2734 return; 2735 } 2736 if (!getGoodToGo()) { 2737 updateStatus(); 2738 return; 2739 } 2740 2741 List imageList = getImageList(); 2742 if ((imageList == null) || (imageList.isEmpty())) { 2743 return; 2744 } 2745 2746 // Check for size threshold 2747 final int[] dim = { 0, 0 }; 2748 AddeImageDescriptor aid = (AddeImageDescriptor) imageList.get(0); 2749 dim[0] = aid.getImageInfo().getElements(); 2750 dim[1] = aid.getImageInfo().getLines(); 2751 // System.err.println("dim:" + dim[0] + " x " + dim[1] + " # images:" 2752 // + imageList.size()); 2753 int numPixels = dim[0] * dim[1] * imageList.size(); 2754 double megs = (4 * numPixels) / (double) 1000000; 2755 2756 //DAVEP: take this out--it should be warning in the data source, not the chooser 2757 boolean doSizeCheck = false; 2758 if (megs > SIZE_THRESHOLD && doSizeCheck) { 2759 final JCheckBox maintainSize = new JCheckBox( 2760 "Maintain spatial extent", false); 2761 final JLabel sizeLbl = new JLabel(StringUtil.padRight(" " 2762 + ((double) ((int) megs * 100)) / 100.0 + " MB", 14)); 2763 GuiUtils.setFixedWidthFont(sizeLbl); 2764 final List[] listHolder = { imageList }; 2765 final JSlider slider = new JSlider(2, (int) megs, (int) megs); 2766 slider.setMajorTickSpacing((int) (megs - 2) / 10); 2767 slider.setMinorTickSpacing((int) (megs - 2) / 10); 2768 // slider.setPaintTicks(true); 2769 slider.setSnapToTicks(true); 2770 final long timeNow = System.currentTimeMillis(); 2771 ChangeListener sizeListener = new javax.swing.event.ChangeListener() { 2772 public void stateChanged(ChangeEvent evt) { 2773 // A hack so we don't respond to the first event that we get 2774 // from the slider when 2775 // the dialog is first shown 2776 if (System.currentTimeMillis() - timeNow < 500) 2777 return; 2778 JSlider slider = (JSlider) evt.getSource(); 2779 int pixelsPerImage = 1000000 * slider.getValue() 2780 / listHolder[0].size() / 4; 2781 double aspect = dim[1] / (double) dim[0]; 2782 int nx = (int) Math.sqrt(pixelsPerImage / aspect); 2783 int ny = (int) (aspect * nx); 2784 if (maintainSize.isSelected()) { 2785 // doesn't work 2786 lineMagSlider.setValue(getLineMagValue() - 1); 2787 lineMagSliderChanged(true); 2788 } else { 2789 numElementsFld.setText("" + nx); 2790 numLinesFld.setText("" + ny); 2791 } 2792 listHolder[0] = getImageList(); 2793 AddeImageDescriptor aid = (AddeImageDescriptor) listHolder[0] 2794 .get(0); 2795 dim[0] = aid.getImageInfo().getElements(); 2796 dim[1] = aid.getImageInfo().getLines(); 2797 int numPixels = dim[0] * dim[1] * listHolder[0].size(); 2798 double nmegs = (4 * numPixels) / (double) 1000000; 2799 sizeLbl.setText(StringUtil.padRight(" " 2800 + ((double) ((int) nmegs * 100)) / 100.0 + " MB", 2801 14)); 2802 } 2803 }; 2804 slider.addChangeListener(sizeListener); 2805 2806 JComponent msgContents = GuiUtils 2807 .vbox( 2808 new JLabel( 2809 "<html>You are about to load " 2810 + megs 2811 + " MB of imagery.<br>Are you sure you want to do this?<p><hr><p></html>"), 2812 GuiUtils.inset(GuiUtils.leftCenterRight(new JLabel( 2813 "Change Size: "), 2814 GuiUtils.inset(slider, 5), sizeLbl), 5)); 2815 2816 if (!GuiUtils.askOkCancel("Image Size", msgContents)) { 2817 return; 2818 } 2819 imageList = listHolder[0]; 2820 } 2821 2822 ImageDataset ids = new ImageDataset(getDatasetName(), imageList); 2823 // make properties Hashtable to hand the station name 2824 // to the AddeImageDataSource 2825 Hashtable ht = new Hashtable(); 2826 ht.put(DataSelection.PROP_CHOOSERTIMEMATCHING, getDoTimeDrivers()); 2827 getDataSourceProperties(ht); 2828 Object bandName = getSelectedBandName(); 2829 if (bandName != null && !(bandName.equals(ALLBANDS.toString()))) { 2830 ht.put(DATA_NAME_KEY, bandName); 2831 } 2832 ht.put("allBands", bandDirs); 2833 makeDataSource(ids, getDataSourceId(), ht); 2834 saveServerState(); 2835 // uncheck the check box every time click the add source button 2836 drivercbx.setSelected(false); 2837 enableTimeWidgets(); 2838 setDoTimeDrivers(false); 2839 } 2840 2841 /** 2842 * Return the data source ID. Used by extending classes. 2843 */ 2844 @Override protected String getDataSourceId() { 2845 return "ADDE.IMAGE"; 2846 } 2847 2848 /** 2849 * Get the DataSource properties 2850 * 2851 * @param ht 2852 * Hashtable of properties 2853 */ 2854 @Override protected void getDataSourceProperties(Hashtable ht) { 2855 super.getDataSourceProperties(ht); 2856 ht.put(DATASET_NAME_KEY, getDatasetName()); 2857 ht.put(ImageDataSource.PROP_BANDINFO, getSelectedBandInfos()); 2858 } 2859 2860 /** 2861 * _more_ 2862 * 2863 * @return _more_ 2864 */ 2865 protected List processPropertyComponents() { 2866 List bottomComps = new ArrayList(); 2867 getBottomComponents(bottomComps); 2868 for (int i = 0; i < bottomComps.size(); i++) { 2869 addDescComp((JComponent) bottomComps.get(i)); 2870 } 2871 return bottomComps; 2872 } 2873 2874 /** 2875 * Make the UI for this selector. 2876 * 2877 * @return The gui 2878 */ 2879 @Override public JComponent doMakeContents() { 2880 JPanel myPanel = new JPanel(); 2881 2882 JLabel timesLabel = McVGuiUtils.makeLabelRight("Times:"); 2883 addDescComp(timesLabel); 2884 2885 JPanel timesPanel = makeTimesPanel(); 2886 timesPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); 2887 addDescComp(timesPanel); 2888 2889 JLabel imageLabel = McVGuiUtils.makeLabelRight("Other:"); 2890 addDescComp(imageLabel); 2891 2892 List comps = new ArrayList(); 2893 comps.addAll(processPropertyComponents()); 2894 GuiUtils.tmpInsets = GRID_INSETS; 2895 JPanel imagePanel = GuiUtils.doLayout(comps, 2, GuiUtils.WT_NY, GuiUtils.WT_N); 2896 imagePanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); 2897 2898 GroupLayout layout = new GroupLayout(myPanel); 2899 myPanel.setLayout(layout); 2900 layout.setHorizontalGroup(layout.createParallelGroup(LEADING) 2901 .addGroup(layout.createSequentialGroup() 2902 .addGroup(layout.createParallelGroup(LEADING) 2903 .addGroup(layout.createSequentialGroup() 2904 .addComponent(descriptorLabel) 2905 .addGap(GAP_RELATED) 2906 .addComponent(descriptorComboBox)) 2907 .addGroup(layout.createSequentialGroup() 2908 .addComponent(timesLabel) 2909 .addGap(GAP_RELATED) 2910 .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 2911 .addGroup(layout.createSequentialGroup() 2912 .addComponent(imageLabel) 2913 .addGap(GAP_RELATED) 2914 .addComponent(imagePanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))))); 2915 2916 layout.setVerticalGroup(layout.createParallelGroup(LEADING) 2917 .addGroup(layout.createSequentialGroup() 2918 .addGroup(layout.createParallelGroup(BASELINE) 2919 .addComponent(descriptorLabel) 2920 .addComponent(descriptorComboBox)) 2921 .addPreferredGap(RELATED) 2922 .addGroup(layout.createParallelGroup(LEADING) 2923 .addComponent(timesLabel) 2924 .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 2925 .addPreferredGap(RELATED) 2926 .addGroup(layout.createParallelGroup(LEADING) 2927 .addComponent(imageLabel) 2928 .addComponent(imagePanel)))); 2929 2930 setInnerPanel(myPanel); 2931 return super.doMakeContents(); 2932 } 2933 2934 public JComponent doMakeContents(boolean doesOverride) { 2935 return doesOverride ? super.doMakeContents() : doMakeContents(); 2936 } 2937 2938}