001 /* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2013 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029 package edu.wisc.ssec.mcidasv.chooser; 030 031 import static javax.swing.GroupLayout.DEFAULT_SIZE; 032 import static javax.swing.GroupLayout.Alignment.BASELINE; 033 import static javax.swing.GroupLayout.Alignment.LEADING; 034 import static javax.swing.GroupLayout.Alignment.TRAILING; 035 import static javax.swing.LayoutStyle.ComponentPlacement.RELATED; 036 import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED; 037 038 import java.awt.Component; 039 import java.util.ArrayList; 040 import java.util.List; 041 042 import javax.swing.GroupLayout; 043 import javax.swing.JButton; 044 import javax.swing.JComboBox; 045 import javax.swing.JComponent; 046 import javax.swing.JLabel; 047 import javax.swing.JPanel; 048 049 import org.w3c.dom.Document; 050 import org.w3c.dom.Element; 051 052 import ucar.unidata.idv.chooser.IdvChooserManager; 053 import ucar.unidata.idv.chooser.XmlHandler; 054 import ucar.unidata.util.CatalogUtil; 055 import ucar.unidata.util.GuiUtils; 056 import ucar.unidata.util.WmsUtil; 057 058 import edu.wisc.ssec.mcidasv.Constants; 059 import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 060 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Position; 061 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.TextColor; 062 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width; 063 064 /** 065 * This handles a variety of flavors of xml documents (e.g., thredds 066 * query capability, thredds catalogs, idv menus) to create data 067 * choosers from. It provides a combobox to enter urls to xml 068 * documents. It retrieves the xml and creates a {@link XmlHandler} 069 * based on the type of xml. Currently this class handles two 070 * types of xml: Thredds catalog and Web Map Server (WMS) 071 * capability documents. The XmlHandler does most of the work. 072 * <p> 073 * This class maintains the different xml docs the user has gone 074 * to coupled with the XmlHandler for each doc. It uses this list 075 * to support navigating back and forth through the history of 076 * documents. 077 * 078 * @author IDV development team 079 * @version $Revision$Date: 2011/03/24 16:06:31 $ 080 */ 081 082 083 public class XmlChooser extends ucar.unidata.idv.chooser.XmlChooser implements Constants { 084 085 /** Catalog browser panel */ 086 JPanel catalogPanel; 087 088 /** Catalog browser panel label history */ 089 int labelHistoryIdx = -1; 090 List labelHistory = new ArrayList(); 091 092 /** 093 * Create the <code>XmlChooser</code> 094 * 095 * @param mgr The <code>IdvChooserManager</code> 096 * @param root The xml root that defines this chooser 097 * 098 */ 099 public XmlChooser(IdvChooserManager mgr, Element root) { 100 super(mgr, root); 101 102 loadButton = McVGuiUtils.makeImageTextButton(ICON_ACCEPT_SMALL, getLoadCommandName()); 103 loadButton.setActionCommand(getLoadCommandName()); 104 loadButton.addActionListener(this); 105 106 } 107 108 private void repaintCatalog() { 109 if (catalogPanel != null) { 110 catalogPanel.invalidate(); 111 catalogPanel.validate(); 112 catalogPanel.repaint(); 113 } 114 String labelName = (String)labelHistory.get(labelHistoryIdx); 115 catalogPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(labelName)); 116 } 117 118 /** 119 * Go back and display the previous document. 120 */ 121 public void goBack() { 122 super.goBack(); 123 labelHistoryIdx--; 124 repaintCatalog(); 125 } 126 127 /** 128 * Go forward and display the next document in the history list. 129 */ 130 public void goForward() { 131 super.goForward(); 132 labelHistoryIdx++; 133 repaintCatalog(); 134 } 135 136 /** 137 * Add a labeled border to the catalog browser indicating the data type 138 */ 139 protected void makeUi(Document doc, Element xmlRoot, String path) { 140 super.makeUi(doc, xmlRoot, path); 141 142 String tagName = xmlRoot.getTagName(); 143 String labelName = "Unknown Catalog Type"; 144 if (tagName.equals(WmsUtil.TAG_WMS1) || tagName.equals(WmsUtil.TAG_WMS2)) labelName = "Web Map Service"; 145 else if (tagName.equals(CatalogUtil.TAG_CATALOG)) labelName = "THREDDS"; 146 else if (tagName.equals("menus")) labelName = "Menu"; 147 148 labelHistoryIdx++; 149 labelHistory.add(labelHistoryIdx, labelName); 150 repaintCatalog(); 151 } 152 153 private JLabel statusLabel = new JLabel("Status"); 154 155 @Override 156 public void setStatus(String statusString, String foo) { 157 if (statusString == null) 158 statusString = ""; 159 statusLabel.setText(statusString); 160 } 161 162 /** 163 * Create and return the Gui contents. 164 * 165 * @return The gui contents. 166 */ 167 protected JComponent doMakeContents() { 168 JComponent parentContents = super.doMakeContents(); 169 170 // Pull apart the panels 171 // Expected: 172 // Top: URL chooser 173 // Center: Catalog chooser 174 // Bottom: chooser buttons 175 // This takes a bit of digging--some of the components are really buried! 176 Component[] parentComps = parentContents.getComponents(); 177 if (parentComps.length != 3 || 178 !(parentComps[0] instanceof JPanel) || 179 !(parentComps[1] instanceof JPanel) || 180 !(parentComps[2] instanceof JPanel) 181 ) return parentContents; 182 183 // Assign file picker to fileComponent 184 JPanel topPanel = (JPanel)parentComps[0]; 185 Component[] panels = topPanel.getComponents(); 186 if (panels.length != 2 || 187 !(panels[0] instanceof JPanel) || 188 !(panels[1] instanceof JPanel) 189 ) return parentContents; 190 // Found the navigation panel 191 JPanel navigationPanel = (JPanel)panels[0]; 192 panels = ((JPanel)panels[1]).getComponents(); 193 if (panels.length != 3 || 194 !(panels[0] instanceof JLabel) || 195 !(panels[1] instanceof JPanel) || 196 !(panels[2] instanceof JButton) 197 ) return parentContents; 198 // Found the button 199 JButton fileButton = (JButton)panels[2]; 200 panels = ((JPanel)panels[1]).getComponents(); 201 if (panels.length != 1 || 202 !(panels[0] instanceof JComboBox) 203 ) return parentContents; 204 JComboBox fileComponent = (JComboBox)panels[0]; 205 McVGuiUtils.setButtonImage(fileButton, ICON_OPEN_SMALL); 206 McVGuiUtils.setComponentWidth(fileButton, Width.DOUBLE); 207 McVGuiUtils.setComponentWidth(fileComponent, Width.DOUBLEDOUBLE); 208 McVGuiUtils.setComponentHeight(fileComponent, fileButton); 209 210 // Deal with the navigation buttons 211 panels = navigationPanel.getComponents(); 212 if (panels.length != 2 || 213 !(panels[0] instanceof JButton) || 214 !(panels[1] instanceof JButton) 215 ) return parentContents; 216 McVGuiUtils.setButtonImage((JButton)panels[0], Constants.ICON_PREVIOUS_SMALL); 217 McVGuiUtils.setButtonImage((JButton)panels[1], Constants.ICON_NEXT_SMALL); 218 JLabel navigationLabel = McVGuiUtils.makeLabelRight("History:"); 219 navigationPanel = GuiUtils.hbox(panels[0], panels[1]); 220 221 // Rearrange the catalog browser and assign it to innerPanel 222 catalogPanel = (JPanel)parentComps[1]; 223 JPanel innerPanel = McVGuiUtils.makeLabeledComponent("Browse:", catalogPanel); 224 225 // Start building the whole thing here 226 JPanel outerPanel = new JPanel(); 227 228 JLabel fileLabel = McVGuiUtils.makeLabelRight("Catalog:"); 229 230 JLabel statusLabelLabel = McVGuiUtils.makeLabelRight(""); 231 232 McVGuiUtils.setLabelPosition(statusLabel, Position.RIGHT); 233 McVGuiUtils.setComponentColor(statusLabel, TextColor.STATUS); 234 235 JButton helpButton = McVGuiUtils.makeImageButton(ICON_HELP, "Show help"); 236 helpButton.setActionCommand(GuiUtils.CMD_HELP); 237 helpButton.addActionListener(this); 238 239 JButton refreshButton = McVGuiUtils.makeImageButton(ICON_REFRESH, "Refresh"); 240 refreshButton.setActionCommand(GuiUtils.CMD_UPDATE); 241 refreshButton.addActionListener(this); 242 243 McVGuiUtils.setButtonImage(loadButton, ICON_ACCEPT_SMALL); 244 McVGuiUtils.setComponentWidth(loadButton, Width.DOUBLE); 245 246 GroupLayout layout = new GroupLayout(outerPanel); 247 outerPanel.setLayout(layout); 248 layout.setHorizontalGroup( 249 layout.createParallelGroup(LEADING) 250 .addGroup(TRAILING, layout.createSequentialGroup() 251 .addGroup(layout.createParallelGroup(TRAILING) 252 .addGroup(layout.createSequentialGroup() 253 .addContainerGap() 254 .addComponent(helpButton) 255 .addGap(GAP_RELATED) 256 .addComponent(refreshButton) 257 .addPreferredGap(RELATED) 258 .addComponent(loadButton)) 259 .addGroup(LEADING, layout.createSequentialGroup() 260 .addContainerGap() 261 .addGroup(layout.createParallelGroup(LEADING) 262 .addGroup(layout.createSequentialGroup() 263 .addComponent(navigationLabel) 264 .addGap(GAP_RELATED) 265 .addComponent(navigationPanel)) 266 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 267 .addGroup(layout.createSequentialGroup() 268 .addComponent(fileLabel) 269 .addGap(GAP_RELATED) 270 .addComponent(fileComponent) 271 .addGap(GAP_UNRELATED) 272 .addComponent(fileButton)) 273 .addGroup(layout.createSequentialGroup() 274 .addComponent(statusLabelLabel) 275 .addGap(GAP_RELATED) 276 .addComponent(statusLabel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))))) 277 .addContainerGap()) 278 ); 279 layout.setVerticalGroup( 280 layout.createParallelGroup(LEADING) 281 .addGroup(layout.createSequentialGroup() 282 .addContainerGap() 283 .addGroup(layout.createParallelGroup(BASELINE) 284 .addComponent(fileLabel) 285 .addComponent(fileComponent) 286 .addComponent(fileButton)) 287 .addPreferredGap(UNRELATED) 288 .addGroup(layout.createParallelGroup(BASELINE) 289 .addComponent(navigationLabel) 290 .addComponent(navigationPanel)) 291 .addPreferredGap(RELATED) 292 293 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 294 .addPreferredGap(UNRELATED) 295 .addGroup(layout.createParallelGroup(BASELINE) 296 .addComponent(statusLabelLabel) 297 .addComponent(statusLabel)) 298 .addPreferredGap(UNRELATED) 299 .addGroup(layout.createParallelGroup(BASELINE) 300 .addComponent(loadButton) 301 .addComponent(refreshButton) 302 .addComponent(helpButton)) 303 .addContainerGap()) 304 ); 305 306 return outerPanel; 307 308 } 309 310 } 311