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