001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2015 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029package edu.wisc.ssec.mcidasv.chooser; 030 031import static javax.swing.GroupLayout.DEFAULT_SIZE; 032import static javax.swing.GroupLayout.PREFERRED_SIZE; 033import static javax.swing.GroupLayout.Alignment.BASELINE; 034import static javax.swing.GroupLayout.Alignment.LEADING; 035import static javax.swing.GroupLayout.Alignment.TRAILING; 036import static javax.swing.LayoutStyle.ComponentPlacement.RELATED; 037import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED; 038 039import java.awt.Component; 040import java.awt.event.ActionEvent; 041import java.awt.event.ActionListener; 042import java.awt.event.ItemEvent; 043import java.awt.event.ItemListener; 044import java.io.IOException; 045import java.net.URI; 046import java.util.ArrayList; 047import java.util.Date; 048import java.util.Hashtable; 049import java.util.List; 050import java.util.Vector; 051 052import javax.swing.GroupLayout; 053import javax.swing.JButton; 054import javax.swing.JComboBox; 055import javax.swing.JComponent; 056import javax.swing.JLabel; 057import javax.swing.JPanel; 058import javax.swing.JTabbedPane; 059 060import org.jdom2.Document; 061import org.jdom2.JDOMException; 062import org.jdom2.Namespace; 063import org.jdom2.input.SAXBuilder; 064import org.w3c.dom.Element; 065 066import thredds.catalog.XMLEntityResolver; 067import ucar.unidata.data.DataSelection; 068import ucar.unidata.data.radar.TDSRadarDatasetCollection; 069import ucar.nc2.units.DateUnit; 070import ucar.unidata.data.radar.RadarQuery; 071import ucar.unidata.geoloc.StationImpl; 072import ucar.unidata.idv.chooser.IdvChooserManager; 073import ucar.unidata.idv.chooser.TimesChooser; 074import ucar.unidata.metdata.NamedStation; 075import ucar.unidata.metdata.NamedStationImpl; 076import ucar.unidata.util.DateSelection; 077import ucar.unidata.util.DateUtil; 078import ucar.unidata.util.DatedThing; 079import ucar.unidata.util.GuiUtils; 080import ucar.unidata.util.LogUtil; 081import ucar.unidata.util.Misc; 082import ucar.unidata.util.PreferenceList; 083import ucar.unidata.util.Product; 084import ucar.unidata.util.TwoFacedObject; 085 086import visad.CommonUnit; 087import visad.DateTime; 088 089import edu.wisc.ssec.mcidasv.Constants; 090import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 091import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Position; 092import edu.wisc.ssec.mcidasv.util.McVGuiUtils.TextColor; 093import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width; 094 095 096/** 097 * Created by IntelliJ IDEA. 098 * User: yuanho 099 * Date: Jan 16, 2008 100 * Time: 11:17:51 AM 101 * To change this template use File | Settings | File Templates. 102 */ 103public class TDSRadarChooser extends TimesChooser implements Constants { 104 105 /** The collection */ 106 private TDSRadarDatasetCollection collection; 107 108 109 /** The currently selected station */ 110 private NamedStation selectedStation; 111 112 /** The currently selected level3 product */ 113 private String selectedProduct; 114 115 /** Those urls we connect to */ 116 //"http://motherlode.ucar.edu:8080/thredds/radarServer/catalog.xml"; 117 private String serverUrl; 118 119 /** Each dataset collection URL */ 120 //"http://motherlode.ucar.edu:8080/thredds/radarServer/level2/idd/dataset.xml"; 121 //private String collectionUrl; 122 123 /** Component to hold collections */ 124 private JComboBox collectionSelector; 125 126 /** Component to hold product list */ 127 private JComboBox productComboBox; 128 129 /** Level 3 panel that can be hidden */ 130 private JPanel productPanel; 131 132 /** components that need a server for activation */ 133 private List compsThatNeedServer = new ArrayList(); 134 135 /** components that need a server for activation */ 136 private List level3CompsThatNeedServer = new ArrayList(); 137 138 /** persistent holder for catalog URLS */ 139 private PreferenceList urlListHandler; 140 141 /** catalog URL holder */ 142 private JComboBox urlBox; 143 144 /** ok flag */ 145 private boolean okToDoUrlListEvents = true; 146 147 /** dataset list */ 148 private List datasetList; 149 150 /** Command for connecting */ 151 protected static final String CMD_CONNECT = "cmd.connect"; 152 153 /** _more_ */ 154 private boolean isLevel3; 155 156 /** _more_ */ 157 public static final String[] level3_ExName = { "NVW", "DPA" }; 158 159 160 /** 161 * Create the RadarChooser. 162 * 163 * @param mgr {@code IdvChooserManager} 164 * @param root XML root that defines this chooser. 165 * 166 */ 167 public TDSRadarChooser(IdvChooserManager mgr, Element root) { 168 super(mgr, root); 169 170 loadButton = McVGuiUtils.makeImageTextButton(ICON_ACCEPT_SMALL, getLoadCommandName()); 171 loadButton.setActionCommand(getLoadCommandName()); 172 loadButton.addActionListener(this); 173 174 cancelButton = McVGuiUtils.makeImageButton(ICON_CANCEL, "Cancel"); 175 cancelButton.setActionCommand(GuiUtils.CMD_CANCEL); 176 cancelButton.addActionListener(this); 177 cancelButton.setEnabled(false); 178 179 } 180 181 182 183 /** 184 * Handle the update event. Just pass it through to the imageChooser 185 */ 186 public void doUpdate() { 187 if ((serverUrl == null) || (datasetList == null) 188 || (datasetList.size() == 0) || (selectedProduct == null)) { 189 if (urlBox != null) { 190 setServer((String) urlBox.getSelectedItem()); 191 } 192 return; 193 } 194 Misc.run(this, "stationOrProductChanged"); 195 } 196 197 198 199 /** 200 * Update the status of the gui 201 */ 202 protected void updateStatus() { 203 super.updateStatus(); 204 if (serverUrl == null) { 205 setHaveData(false); 206 setStatus("Please connect to the server"); 207 } 208 else if (selectedStation == null) { 209 setHaveData(false); 210 setStatus("Please select a station", "stations"); 211 } 212 else if (isLevel3 && (selectedProduct == null)) { 213 setHaveData(false); 214 setStatus("Please select a level 3 product", "products"); 215 } 216 else { 217 boolean haveTimesSelected; 218 if (getDoAbsoluteTimes()) { 219 haveTimesSelected = getSelectedAbsoluteTimes().size() > 0; 220 } else { 221 haveTimesSelected = true; 222 } 223 setHaveData(haveTimesSelected); 224 if (haveTimesSelected) { 225 setStatus("Press \"" + CMD_LOAD + "\" to load the selected radar data", "buttons"); 226 } else { 227 setStatus("Please select times", "timepanel"); 228 } 229 } 230 GuiUtils.enableTree(loadButton, getHaveData()); 231 if (drivercbx != null) { 232 drivercbx.setEnabled(anyTimeDrivers() && getHaveData()); 233 } 234 } 235 236 237 238 /** 239 * Handle when there are newly selected stations 240 * 241 * @param stations list of newly selected stations 242 */ 243 protected void newSelectedStations(List stations) { 244 super.newSelectedStations(stations); 245 if ((stations == null) || (stations.size() == 0)) { 246 selectedStation = null; 247 } else { 248 NamedStation newStation = (NamedStation) stations.get(0); 249 if (Misc.equals(newStation, selectedStation)) { 250 return; 251 } 252 selectedStation = newStation; 253 } 254 Misc.run(TDSRadarChooser.this, "stationOrProductChanged"); 255 } 256 257 258 /** A widget for the list of dataset descriptors */ 259 260 261 /** Flag to keep from infinite looping */ 262 private boolean ignoreProductChange = false; 263 264 /** Selection label text */ 265 protected static final String LABEL_SELECT = " -- Select -- "; 266 267 /** 268 * _more_ 269 */ 270 protected void productChanged() { 271 stationOrProductChanged(); 272 // updateStatus(); 273 } 274 275 /** 276 * Reset the descriptor stuff 277 */ 278 private void resetProductBox() { 279 ignoreProductChange = true; 280 productComboBox.setSelectedItem(LABEL_SELECT); 281 ignoreProductChange = false; 282 } 283 284 /** 285 * Should we update on first display 286 * 287 * @return true 288 */ 289 protected boolean shouldDoUpdateOnFirstDisplay() { 290 return false; 291 } 292 293 /** 294 * Set the server 295 * 296 * @param s the server URL 297 */ 298 private void setServer(String s) { 299 datasetList = new ArrayList(); 300 serverUrl = s; 301 try { 302 List collections = getRadarCollections(serverUrl); 303 GuiUtils.setListData(collectionSelector, collections); 304 } catch (Exception e) { 305 GuiUtils.setListData(collectionSelector, new ArrayList()); 306 } 307 } 308 309 /** 310 * Set the active collection 311 * 312 * @param s collection URL 313 */ 314 private void setCollection(String s) { 315 isLevel3 = false; 316 GuiUtils.enableComponents(level3CompsThatNeedServer, false); 317 productPanel.setVisible(false); 318 GuiUtils.enableComponents(compsThatNeedServer, true); 319 if (drivercbx != null) { 320 drivercbx.setEnabled(anyTimeDrivers() && getHaveData()); 321 } 322 setAbsoluteTimes(new ArrayList()); 323 selectedProduct = null; 324 selectedStation = null; 325 Misc.run(this, "initializeCollection", s); 326 } 327 328 /** 329 * _more_ 330 * 331 * @param s _more_ 332 */ 333 private void setLevel3Collection(String s) { 334 isLevel3 = true; 335 GuiUtils.enableComponents(level3CompsThatNeedServer, true); 336 productPanel.setVisible(true); 337 GuiUtils.enableComponents(compsThatNeedServer, true); 338 if (drivercbx != null) { 339 drivercbx.setEnabled(anyTimeDrivers() && getHaveData()); 340 } 341 setAbsoluteTimes(new ArrayList()); 342 selectedProduct = null; 343 selectedStation = null; 344 Misc.run(this, "initializeLevel3Collection", s); 345 } 346 347 /** 348 * Add a component that needs to have a valid server 349 * 350 * @param comp the component 351 * 352 * @return the component 353 */ 354 protected JComponent addServerComp(JComponent comp) { 355 compsThatNeedServer.add(comp); 356 return comp; 357 } 358 359 /** 360 * Add a component that needs to have a valid server 361 * 362 * @param comp the component 363 * 364 * @return the component 365 */ 366 protected JComponent addLevel3ServerComp(JComponent comp) { 367 level3CompsThatNeedServer.add(comp); 368 return comp; 369 } 370 371 /** 372 * Get the radar collections for the given server URL 373 * 374 * @param radarServerURL server URL 375 * 376 * @return a map of the collection names to URL 377 */ 378 private List getRadarCollections(String radarServerURL) { 379 SAXBuilder builder; 380 Document doc = null; 381 XMLEntityResolver jaxp = new XMLEntityResolver(true); 382 builder = jaxp.getSAXBuilder(); 383 List collections = new ArrayList(); 384 385 try { 386 doc = builder.build(radarServerURL); 387 } catch (JDOMException e) { 388 userMessage("Invalid catalog"); 389 //e.printStackTrace(); 390 } catch (IOException e) { 391 userMessage("Unable to open catalog"); 392 //e.printStackTrace(); 393 } 394 395 org.jdom2.Element rootElem = doc.getRootElement(); 396 org.jdom2.Element serviceElem = readElements(rootElem, "service"); 397 String uriBase = serviceElem.getAttributeValue("base"); 398 org.jdom2.Element dsElem = readElements(rootElem, "dataset"); 399 String naming = "catalogRef"; 400 Namespace nss = rootElem.getNamespace("xlink"); 401 List children = dsElem.getChildren(); 402 for (int j = 0; j < children.size(); j++) { 403 org.jdom2.Element child = (org.jdom2.Element) children.get(j); 404 String childName = child.getName(); 405 if (childName.equals(naming)) { 406 //String id = child.getAttributeValue("ID"); 407 String desc = child.getAttributeValue("title", nss); 408 String urlpath = child.getAttributeValue("href", nss); 409 String[] c = radarServerURL.split(uriBase); //.replaceFirst("catalog.xml", ""); 410 String ul = c[0] + uriBase + urlpath; 411 TwoFacedObject twoObj = new TwoFacedObject(desc, ul); 412 collections.add(twoObj); 413 //collections.put(desc, ul); 414 } 415 416 } 417 418 return collections; 419 } 420 421 /** 422 * Read the elements 423 * 424 * @param elem element 425 * @param eleName element name 426 * 427 * @return an element 428 */ 429 public org.jdom2.Element readElements(org.jdom2.Element elem, 430 String eleName) { 431 List children = elem.getChildren(); 432 for (int j = 0; j < children.size(); j++) { 433 org.jdom2.Element child = (org.jdom2.Element) children.get(j); 434 String childName = child.getName(); 435 if (childName.equals(eleName)) { 436 return child; 437 } 438 } 439 return null; 440 } 441 442 /** 443 * Make the collection. If there is an error, pop up a user message. 444 * 445 * @param url URL for the collection 446 */ 447 public void initializeCollection(String url) { 448 449 List<NamedStationImpl> stations = new ArrayList<NamedStationImpl>(); 450 try { 451 StringBuffer errlog = new StringBuffer(); 452 try { 453 collection = TDSRadarDatasetCollection.factory("test", url, 454 errlog); 455 } catch (Exception exc) { 456 userMessage("Invalid catalog"); 457 458 return; 459 } 460 List tdsStations = collection.getRadarStations(); 461 for (int i = 0; i < tdsStations.size(); i++) { 462 StationImpl stn = (StationImpl) tdsStations.get(i); 463 // thredds.catalog.query.Location loc = stn.getLocation(); 464 //TODO: need better station need to switch lat lon 465 NamedStationImpl station = 466 new NamedStationImpl(stn.getName(), stn.getName(), 467 stn.getLatitude(), 468 stn.getLongitude(), 469 stn.getAltitude(), CommonUnit.meter); 470 stations.add(station); 471 472 } 473 474 getStationMap().setStations(stations); 475 } catch (Exception exc) { 476 userMessage("Unable to load stations"); 477 return; 478 } 479 urlListHandler.saveState(urlBox); 480 } 481 482 /** 483 * _more_ 484 * 485 * @param url _more_ 486 */ 487 public void initializeLevel3Collection(String url) { 488 489 List<NamedStationImpl> stations = new ArrayList<NamedStationImpl>(); 490 List<Product> products; 491 List<String> exProducts = new ArrayList<String>(); 492 493 for(String ename: level3_ExName){ 494 exProducts.add(ename); 495 } 496 497 try { 498 StringBuffer errlog = new StringBuffer(); 499 try { 500 collection = TDSRadarDatasetCollection.factory("test", url, 501 errlog); 502 } catch (Exception exc) { 503 userMessage("Invalid catalog"); 504 return; 505 } 506 products = collection.getRadarProducts(); 507 List tdsStations = collection.getRadarStations(); 508 for (int i = 0; i < tdsStations.size(); i++) { 509 StationImpl stn = (StationImpl) tdsStations.get(i); 510 // thredds.catalog.query.Location loc = stn.getLocation(); 511 //TODO: need better station need to switch lat lon 512 NamedStationImpl station = 513 new NamedStationImpl(stn.getName(), stn.getName(), 514 stn.getLatitude(), 515 stn.getLongitude(), 516 stn.getAltitude(), CommonUnit.meter); 517 stations.add(station); 518 519 } 520 List<TwoFacedObject> productNames = new ArrayList(); 521 for (Product product : products) { 522 // if ( !product.getID().contains("DPA") 523 // && !product.getID().contains("NVW")) { 524 if ( !exProducts.contains(product.getID())) { 525 String lable = product.getName() + " (" + product.getID() 526 + ")"; 527 TwoFacedObject twoObj = new TwoFacedObject(lable, 528 product.getID()); 529 productNames.add(twoObj); 530 } 531 } 532 GuiUtils.setListData(productComboBox, productNames); 533 534 // GuiUtils.setListData(dataTypeComboBox, dataTypes); 535 getStationMap().setStations(stations); 536 } catch (Exception exc) { 537 userMessage("Unable to load stations"); 538 return; 539 } 540 urlListHandler.saveState(urlBox); 541 } 542 543 544 /** 545 * Handle when the user has selected a new station 546 */ 547 public void stationOrProductChanged() { 548 Vector times = new Vector(); 549 setHaveData(false); 550 if ((!isLevel3 && selectedStation != null) || 551 (isLevel3 && selectedStation != null && selectedProduct != null)) { 552 List timeSpan = collection.getRadarTimeSpan(); 553 Date fromDate = DateUnit.getStandardOrISO((String) timeSpan.get(0)); 554 //Date toDate = DateUnit.getStandardOrISO((String) timeSpan.get(1)); 555 Date toDate = new Date(System.currentTimeMillis() 556 + DateUtil.daysToMillis(1)); 557 //Go back 10 years (or so) 558 //Date fromDate = new Date(System.currentTimeMillis() 559 // - DateUtil.daysToMillis(365 * 10)); 560 try { 561 showWaitCursor(); 562 setAbsoluteTimes(new ArrayList()); 563 setStatus("Reading times for station: " + selectedStation, 564 ""); 565 // LogUtil.message("Reading times for station: " 566 // + selectedStation); 567 String pid = null; 568 if(isLevel3) 569 pid = TwoFacedObject.getIdString( 570 productComboBox.getSelectedItem()); 571 List allTimes = 572 collection.getRadarStationTimes(selectedStation.getID(), 573 pid, fromDate, toDate); 574 575 // if(allTimes.size() == 0) { 576 // toDate = new Date(System.currentTimeMillis() 577 // + DateUtil.daysToMillis(1)); 578 // allTimes = 579 // collection.getRadarStationTimes(selectedStation.getID(), 580 // pid, fromDate, toDate); 581 // } 582 583 for (int timeIdx = 0; timeIdx < allTimes.size(); timeIdx++) { 584 Object timeObj = allTimes.get(timeIdx); 585 Date date; 586 if (timeObj instanceof Date) { 587 date = (Date) timeObj; 588 } else { 589 date = DateUnit.getStandardOrISO(timeObj.toString()); 590 } 591 times.add(new DateTime(date)); 592 } 593 // LogUtil.message(""); 594 showNormalCursor(); 595 } catch (Exception exc) { 596 userMessage("Error reading times for station: " 597 + selectedStation); 598 //logException("Getting times for station: " + selectedStation, 599 // exc); 600 setStatus("Select a different collection", "collections"); 601 showNormalCursor(); 602 return; 603 } 604 } 605 setAbsoluteTimes(times); 606 updateStatus(); 607 } 608 609 610 611 612 613 /** 614 * Load the data 615 */ 616 public void doLoadInThread() { 617 // to the CDMRadarDataSource 618 Hashtable ht = new Hashtable(); 619 if (selectedStation != null) { 620 ht.put(ucar.unidata.data.radar.RadarDataSource.STATION_LOCATION, 621 selectedStation.getNamedLocation()); 622 ht.put(DataSelection.PROP_CHOOSERTIMEMATCHING, getDoTimeDrivers()); 623 } else { 624 LogUtil.userMessage("No Station selected"); 625 } 626 627 if (isLevel3 && (selectedProduct == null)) { 628 629 LogUtil.userMessage("No Product selected"); 630 } 631 632 try { 633 DateSelection dateSelection = new DateSelection(); 634 String collectionUrl = TwoFacedObject.getIdString( 635 collectionSelector.getSelectedItem()); 636 String pid = null; 637 RadarQuery radarQuery; 638 if (isLevel3) { 639 pid = TwoFacedObject.getIdString( 640 productComboBox.getSelectedItem()); 641 radarQuery = new RadarQuery(collectionUrl, 642 selectedStation.getID(), pid, 643 dateSelection); 644 } else { 645 radarQuery = new RadarQuery(collectionUrl, 646 selectedStation.getID(), 647 dateSelection); 648 } 649 650 List urls = new ArrayList(); 651 652 if (getDoAbsoluteTimes()) { 653 List times = new ArrayList(); 654 List selected = makeDatedObjects(getSelectedAbsoluteTimes()); 655 for (int i = 0; i < selected.size(); i++) { 656 DatedThing datedThing = (DatedThing) selected.get(i); 657 Date date = datedThing.getDate(); 658 times.add(date); 659 URI uri = null; 660 try { 661 uri = collection.getRadarDatasetURI( 662 selectedStation.getID(), pid, date); 663 } catch (Exception excp) { 664 LogUtil.userMessage("incorrect times selected"); 665 return; 666 } 667 urls.add(uri.toString()); 668 } 669 if (urls.size() == 0) { 670 LogUtil.userMessage("No times selected"); 671 return; 672 } 673 dateSelection.setTimes(times); 674 } else { 675 int count = getRelativeTimesList().getSelectedIndex() + 1; 676 if (count == 0) { 677 LogUtil.userMessage("No relative times selected"); 678 return; 679 } 680 Date toDate = new Date(System.currentTimeMillis() 681 + DateUtil.daysToMillis(365 * 100)); 682 //Go back 10 years (or so) 683 Date fromDate = new Date(System.currentTimeMillis() 684 - DateUtil.daysToMillis(365 * 10)); 685 686 dateSelection.setStartFixedTime(fromDate); 687 dateSelection.setEndFixedTime(toDate); 688 dateSelection.setCount(count); 689 } 690 makeDataSource(radarQuery, "FILE.RADAR", ht); 691 } catch (Exception exc) { 692 logException("Loading radar data", exc); 693 } 694 // uncheck the check box every time click the add source button 695 drivercbx.setSelected(false); 696 enableTimeWidgets(); 697 setDoTimeDrivers(false); 698 } 699 700 protected int getNumTimesToSelect() { 701 return 5; 702 } 703 704 /** 705 * Get the default selected index for the relative times list. 706 * 707 * @return default index 708 */ 709 protected int getDefaultRelativeTimeIndex() { 710 return 4; 711 } 712 713 /** 714 * Check the times lists 715 */ 716 protected void checkTimesLists() { 717 super.checkTimesLists(); 718 if (timesCardPanelExtra == null) { 719 return; 720 } 721 if (getDoAbsoluteTimes()) { 722 timesCardPanelExtra.show("absolute"); 723 } else { 724 timesCardPanelExtra.show("relative"); 725 } 726 } 727 728 /** Card panel to hold extra relative and absolute time components */ 729 private GuiUtils.CardLayoutPanel timesCardPanelExtra; 730 731 /** 732 * Add the interval selector to the component. 733 * @return superclass component with extra stuff 734 */ 735 protected JPanel makeTimesPanel() { 736 JComponent extra = getExtraTimeComponent(); 737 GuiUtils.enableTree(extra, false); 738 JPanel timesPanel = makeTimesPanel(extra, null); 739 return timesPanel; 740 } 741 742 /** 743 * Set the relative and absolute extra components 744 */ 745 protected JPanel makeTimesPanel(JComponent relativeCard, JComponent absoluteCard) { 746 JPanel timesPanel = super.makeTimesPanel(false, true, getIdv().getUseTimeDriver()); 747 748 // Make a new timesPanel that has extra components tacked on the bottom, inside the tabs 749 Component[] comps = timesPanel.getComponents(); 750 751 if ((comps.length == 2) && (comps[0] instanceof JTabbedPane) && (comps[1] instanceof JLabel)) { 752 timesCardPanelExtra = new GuiUtils.CardLayoutPanel(); 753 if (relativeCard == null) { 754 relativeCard = new JPanel(); 755 } 756 if (absoluteCard == null) { 757 absoluteCard = new JPanel(); 758 } 759 absoluteCard = GuiUtils.hbox(comps[1], GuiUtils.right(absoluteCard)); 760 timesCardPanelExtra.add(relativeCard, "relative"); 761 timesCardPanelExtra.add(absoluteCard, "absolute"); 762 timesPanel = GuiUtils.centerBottom(comps[0], timesCardPanelExtra); 763 } 764 return timesPanel; 765 } 766 767 /** 768 * Get the time popup widget 769 * 770 * @return a widget for selecting the day 771 */ 772 protected JComponent getExtraTimeComponent() { 773 JPanel filler = new JPanel(); 774 McVGuiUtils.setComponentHeight(filler, new JComboBox()); 775 return filler; 776 } 777 778 /** 779 * Make the contents 780 * 781 * @return the contents 782 */ 783 protected JPanel doMakeInnerPanel() { 784 JPanel myPanel = new JPanel(); 785 786 JLabel collectionLabel = McVGuiUtils.makeLabelRight("Collection:"); 787 788 collectionSelector = new JComboBox(); 789 collectionSelector.addItemListener(new ItemListener() { 790 public void itemStateChanged(ItemEvent e) { 791 newSelectedStations(new ArrayList()); 792 if (collectionSelector.getSelectedItem() == null) { 793 return; 794 } 795 String collectionUrl = 796 TwoFacedObject.getIdString( 797 collectionSelector.getSelectedItem()); 798 799 if (collectionUrl.contains("level3")) { 800 setLevel3Collection(collectionUrl); 801 } else { 802 setCollection(collectionUrl); 803 } 804 } 805 806 }); 807 addServerComp(collectionLabel); 808 addServerComp(collectionSelector); 809 810 productComboBox = new JComboBox(); 811 productComboBox.addItemListener(new ItemListener() { 812 public void itemStateChanged(ItemEvent e) { 813 if (productComboBox.getSelectedItem() == null) { 814 return; 815 } 816 selectedProduct = 817 productComboBox.getSelectedItem().toString(); 818 resetProductBox(); 819 productChanged(); 820 } 821 822 }); 823 addLevel3ServerComp(productComboBox); 824 825 productPanel = McVGuiUtils.makeLabeledComponent("Product:", productComboBox); 826 827 JLabel stationLabel = McVGuiUtils.makeLabelRight("Station:"); 828 addServerComp(stationLabel); 829 830 JComponent stationPanel = getStationMap(); 831 registerStatusComp("stations", stationPanel); 832 addServerComp(stationPanel); 833 834 JLabel timesLabel = McVGuiUtils.makeLabelRight("Times:"); 835 addServerComp(timesLabel); 836 837 JPanel timesPanel = makeTimesPanel(); 838 timesPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); 839 addServerComp(timesPanel); 840 841 GuiUtils.enableComponents(compsThatNeedServer, false); 842 GuiUtils.enableComponents(level3CompsThatNeedServer, false); 843 productPanel.setVisible(false); 844 845 GroupLayout layout = new GroupLayout(myPanel); 846 myPanel.setLayout(layout); 847 layout.setHorizontalGroup( 848 layout.createParallelGroup(LEADING) 849 .addGroup(layout.createSequentialGroup() 850 .addGroup(layout.createParallelGroup(LEADING) 851 .addGroup(layout.createSequentialGroup() 852 .addComponent(collectionLabel) 853 .addGap(GAP_RELATED) 854 .addComponent(collectionSelector, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 855 .addComponent(productPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 856 .addGroup(layout.createSequentialGroup() 857 .addComponent(stationLabel) 858 .addGap(GAP_RELATED) 859 .addComponent(stationPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 860 .addGroup(layout.createSequentialGroup() 861 .addComponent(timesLabel) 862 .addGap(GAP_RELATED) 863 .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)))) 864 ); 865 layout.setVerticalGroup( 866 layout.createParallelGroup(LEADING) 867 .addGroup(layout.createSequentialGroup() 868 .addGroup(layout.createParallelGroup(BASELINE) 869 .addComponent(collectionLabel) 870 .addComponent(collectionSelector) 871 .addComponent(productPanel)) 872 .addPreferredGap(RELATED) 873 .addGroup(layout.createParallelGroup(LEADING) 874 .addComponent(stationLabel) 875 .addComponent(stationPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 876 .addPreferredGap(RELATED) 877 .addGroup(layout.createParallelGroup(LEADING) 878 .addComponent(timesLabel) 879 .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 880 .addPreferredGap(RELATED)) 881 ); 882 883 return myPanel; 884 } 885 886 private JPanel innerPanel = doMakeInnerPanel(); 887 888 private JLabel statusLabel = new JLabel("Status"); 889 890 @Override 891 public void setStatus(String statusString, String foo) { 892 if (statusString == null) 893 statusString = ""; 894 statusLabel.setText(statusString); 895 } 896 897 protected void setInnerPanel(JPanel newInnerPanel) { 898 innerPanel = newInnerPanel; 899 } 900 901 /** 902 * Make the UI for this selector. 903 * 904 * Thank you NetBeans for helping with the layout! 905 * 906 * @return The GUI. 907 */ 908 public JComponent doMakeContents() { 909 JPanel outerPanel = new JPanel(); 910 911 JLabel serverLabel = McVGuiUtils.makeLabelRight("Catalog:"); 912 913 //Get the list of catalogs but remove the old catalog.xml entry 914 urlListHandler = getPreferenceList(PREF_TDSRADARSERVER); 915 916 ActionListener catListListener = new ActionListener() { 917 public void actionPerformed(ActionEvent ae) { 918 if ( !okToDoUrlListEvents) { 919 return; 920 } 921 setServer((String) urlBox.getSelectedItem()); 922 } 923 }; 924 925 urlBox = urlListHandler.createComboBox(GuiUtils.CMD_UPDATE, catListListener, true); 926 McVGuiUtils.setComponentWidth(urlBox, Width.DOUBLEDOUBLE); 927 928 // productComboBox gets created a little too tall--set to same height as urlBox 929 if (productComboBox!=null) 930 McVGuiUtils.setComponentHeight(productComboBox, urlBox); 931 932 JButton connectButton = McVGuiUtils.makeImageTextButton(ICON_CONNECT_SMALL, "Connect"); 933 McVGuiUtils.setComponentWidth(connectButton, Width.DOUBLE); 934 connectButton.setActionCommand(GuiUtils.CMD_UPDATE); 935 connectButton.addActionListener(this); 936 937 JLabel statusLabelLabel = McVGuiUtils.makeLabelRight(""); 938 939 statusLabel.setText("Status"); 940 McVGuiUtils.setLabelPosition(statusLabel, Position.RIGHT); 941 McVGuiUtils.setComponentColor(statusLabel, TextColor.STATUS); 942 943 JButton helpButton = McVGuiUtils.makeImageButton(ICON_HELP, "Show help"); 944 helpButton.setActionCommand(GuiUtils.CMD_HELP); 945 helpButton.addActionListener(this); 946 947 JButton refreshButton = McVGuiUtils.makeImageButton(ICON_REFRESH, "Refresh"); 948 refreshButton.setActionCommand(GuiUtils.CMD_UPDATE); 949 refreshButton.addActionListener(this); 950 951 McVGuiUtils.setComponentWidth(loadButton, Width.DOUBLE); 952 953 GroupLayout layout = new GroupLayout(outerPanel); 954 outerPanel.setLayout(layout); 955 layout.setHorizontalGroup( 956 layout.createParallelGroup(LEADING) 957 .addGroup(TRAILING, layout.createSequentialGroup() 958 .addGroup(layout.createParallelGroup(TRAILING) 959 .addGroup(layout.createSequentialGroup() 960 .addContainerGap() 961 .addComponent(helpButton) 962 .addGap(GAP_RELATED) 963 .addComponent(refreshButton) 964 .addGap(GAP_RELATED) 965 .addComponent(cancelButton) 966 .addPreferredGap(RELATED) 967 .addComponent(loadButton)) 968 .addGroup(LEADING, layout.createSequentialGroup() 969 .addContainerGap() 970 .addGroup(layout.createParallelGroup(LEADING) 971 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 972 .addGroup(layout.createSequentialGroup() 973 .addComponent(serverLabel) 974 .addGap(GAP_RELATED) 975 .addComponent(urlBox, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 976 .addGap(GAP_UNRELATED) 977 .addComponent(connectButton)) 978 .addGroup(layout.createSequentialGroup() 979 .addComponent(statusLabelLabel) 980 .addGap(GAP_RELATED) 981 .addComponent(statusLabel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))))) 982 .addContainerGap()) 983 ); 984 layout.setVerticalGroup( 985 layout.createParallelGroup(LEADING) 986 .addGroup(layout.createSequentialGroup() 987 .addContainerGap() 988 .addGroup(layout.createParallelGroup(BASELINE) 989 .addComponent(serverLabel) 990 .addComponent(urlBox) 991 .addComponent(connectButton)) 992 .addPreferredGap(UNRELATED) 993 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 994 .addPreferredGap(UNRELATED) 995 .addGroup(layout.createParallelGroup(BASELINE) 996 .addComponent(statusLabelLabel) 997 .addComponent(statusLabel)) 998 .addPreferredGap(UNRELATED) 999 .addGroup(layout.createParallelGroup(BASELINE) 1000 .addComponent(loadButton) 1001 .addComponent(cancelButton) 1002 .addComponent(refreshButton) 1003 .addComponent(helpButton)) 1004 .addContainerGap()) 1005 ); 1006 1007 return outerPanel; 1008 1009 } 1010 1011} 1012