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