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