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