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