001/* 002 * $Id: RaobChooser.java,v 1.11 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.PREFERRED_SIZE; 035import static javax.swing.GroupLayout.Alignment.BASELINE; 036import static javax.swing.GroupLayout.Alignment.LEADING; 037import static javax.swing.GroupLayout.Alignment.TRAILING; 038import static javax.swing.LayoutStyle.ComponentPlacement.RELATED; 039import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED; 040 041import java.awt.Color; 042import java.awt.Component; 043import java.awt.Dimension; 044 045import javax.swing.GroupLayout; 046import javax.swing.JButton; 047import javax.swing.JComponent; 048import javax.swing.JLabel; 049import javax.swing.JPanel; 050import javax.swing.JScrollPane; 051import javax.swing.JTextField; 052 053import org.w3c.dom.Element; 054 055import ucar.unidata.idv.chooser.IdvChooserManager; 056import ucar.unidata.util.GuiUtils; 057import ucar.unidata.xml.XmlUtil; 058import edu.wisc.ssec.mcidasv.Constants; 059import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 060import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Position; 061import edu.wisc.ssec.mcidasv.util.McVGuiUtils.TextColor; 062import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width; 063 064 065/** 066 * A chooser class for selecting Raob data. 067 * Mostly just a wrapper around a 068 * {@link ucar.unidata.view.sounding.SoundingSelector} 069 * that does most of the work 070 * 071 * @author IDV development team 072 * @version $Revision: 1.11 $Date: 2011/03/24 16:06:31 $ 073 */ 074 075 076public class RaobChooser extends ucar.unidata.idv.chooser.RaobChooser implements Constants { 077 078 /** 079 * Construct a <code>RaobChooser</code> using the manager 080 * and the root XML that defines this object. 081 * 082 * @param mgr <code>IdvChooserManager</code> that controls this chooser. 083 * @param root root element of the XML that defines this object 084 */ 085 public RaobChooser(IdvChooserManager mgr, Element root) { 086 super(mgr, root); 087 } 088 089 /** 090 * Make the contents 091 * 092 * @return the contents 093 */ 094 protected JPanel doMakeInnerPanel(JPanel fromPanel) { 095 096 // Get the station panel 097 Component[] fromComps = fromPanel.getComponents(); 098 099 if (fromComps.length != 2 || 100 !(fromComps[0] instanceof JPanel) || 101 !(fromComps[1] instanceof JPanel) 102 ) return fromPanel; 103 JComponent stationPanel = (JPanel)fromComps[1]; 104 // TODO: Yup, these are magic dimension numbers 105 stationPanel.setPreferredSize(new Dimension(300, 252)); 106 Color bgcolor = stationPanel.getBackground(); 107 108 // Get the times panel 109 Component[] panels = ((JPanel)fromComps[0]).getComponents(); 110 if (panels.length < 1 || 111 !(panels[0] instanceof JPanel) 112 ) return fromPanel; 113 panels = ((JPanel)panels[0]).getComponents(); 114 if (panels.length != 4 || 115 !(panels[0] instanceof JLabel) || 116 !(panels[1] instanceof JScrollPane) || 117 !(panels[2] instanceof JLabel) || 118 !(panels[3] instanceof JScrollPane) 119 ) return fromPanel; 120 121 JScrollPane availablePanel = (JScrollPane)panels[1]; 122 // TODO: Yup, these are magic dimension numbers 123 availablePanel.setPreferredSize(new Dimension(180, 50)); 124 availablePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Available")); 125 availablePanel.setBackground(bgcolor); 126 JScrollPane selectedPanel = (JScrollPane)panels[3]; 127 // TODO: Yup, these are magic dimension numbers 128 selectedPanel.setPreferredSize(new Dimension(170, 50)); 129 selectedPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Selected")); 130 selectedPanel.setBackground(bgcolor); 131 132 // Make the container panel 133 JPanel timesPanel = new JPanel(); 134 135 GroupLayout timesLayout = new GroupLayout(timesPanel); 136 timesPanel.setLayout(timesLayout); 137 timesLayout.setHorizontalGroup( 138 timesLayout.createParallelGroup(LEADING) 139 .addGroup(timesLayout.createSequentialGroup() 140 .addComponent(availablePanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 141 .addGap(GAP_RELATED) 142 .addComponent(selectedPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 143 ) 144 ); 145 timesLayout.setVerticalGroup( 146 timesLayout.createParallelGroup(LEADING) 147 .addGroup(timesLayout.createSequentialGroup() 148 .addGroup(timesLayout.createParallelGroup(TRAILING) 149 .addComponent(selectedPanel, LEADING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 150 .addComponent(availablePanel, LEADING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 151 ) 152 ); 153 154 // TODO: Yup, these are magic dimension numbers 155 JComponent temp = new JPanel(); 156 temp.setPreferredSize(new Dimension(150, 150)); 157 temp.setBorder(javax.swing.BorderFactory.createEtchedBorder()); 158 McVGuiUtils.setComponentHeight(timesPanel, temp); 159 160 JPanel myPanel = new JPanel(); 161 162 JLabel descriptorLabelStatic = McVGuiUtils.makeLabelRight("Soundings:"); 163 JLabel descriptorString = new JLabel("Upper air mandatory and significant levels"); 164 McVGuiUtils.setLabelBold(descriptorString, true); 165 166 JLabel stationLabel = McVGuiUtils.makeLabelRight("Stations:"); 167 168 JLabel timesLabel = McVGuiUtils.makeLabelRight(""); 169 170 GroupLayout layout = new GroupLayout(myPanel); 171 myPanel.setLayout(layout); 172 layout.setHorizontalGroup( 173 layout.createParallelGroup(LEADING) 174 .addGroup(layout.createSequentialGroup() 175 .addGroup(layout.createParallelGroup(LEADING) 176 .addGroup(layout.createSequentialGroup() 177 .addComponent(descriptorLabelStatic) 178 .addGap(GAP_RELATED) 179 .addComponent(descriptorString)) 180 .addGroup(layout.createSequentialGroup() 181 .addComponent(stationLabel) 182 .addGap(GAP_RELATED) 183 .addComponent(stationPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 184 .addGroup(layout.createSequentialGroup() 185 .addComponent(timesLabel) 186 .addGap(GAP_RELATED) 187 .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)))) 188 ); 189 layout.setVerticalGroup( 190 layout.createParallelGroup(LEADING) 191 .addGroup(layout.createSequentialGroup() 192 .addGroup(layout.createParallelGroup(BASELINE) 193 .addComponent(descriptorLabelStatic) 194 .addComponent(descriptorString)) 195 .addPreferredGap(RELATED) 196 .addGroup(layout.createParallelGroup(LEADING) 197 .addComponent(stationLabel) 198 .addComponent(stationPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 199 .addPreferredGap(RELATED) 200 .addGroup(layout.createParallelGroup(LEADING) 201 .addComponent(timesLabel) 202 .addComponent(timesPanel, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 203 .addPreferredGap(RELATED)) 204 ); 205 206 return myPanel; 207 } 208 209 private JLabel statusLabel = new JLabel("Status"); 210 211 @Override 212 public void setStatus(String statusString, String foo) { 213 if (statusString == null) 214 statusString = ""; 215 statusLabel.setText(statusString); 216 } 217 218 /** 219 * Make the GUI 220 * 221 * @return The GUI 222 */ 223 protected JComponent doMakeContents() { 224 Element chooserNode = getXmlNode(); 225 XmlUtil.setAttributes(chooserNode, new String[] { ATTR_SHOWSERVER, "false" }); 226 JComponent parentContents = super.doMakeContents(); 227 228 // Pull apart the panels 229 // Expected: 230 // Top: file chooser 231 // Center: sounding selector 232 // Bottom: chooser buttons 233 // This takes a bit of digging--some of the components are really buried! 234 Component[] parentComps = parentContents.getComponents(); 235 236 // Dig down through all the GuiUtils parents 237 parentComps = ((JComponent)parentComps[0]).getComponents(); 238 parentComps = ((JComponent)parentComps[0]).getComponents(); 239 parentComps = ((JComponent)parentComps[0]).getComponents(); 240 241 if (parentComps.length != 3 || 242 !(parentComps[0] instanceof JPanel) || 243 !(parentComps[1] instanceof JPanel) || 244 !(parentComps[2] instanceof JPanel) 245 ) return parentContents; 246 247 // Assign sounding selector file picker to typeComponent 248 JPanel topPanel = (JPanel)parentComps[0]; 249 Component[] panels = topPanel.getComponents(); 250 if (panels.length < 1 || 251 !(panels[0] instanceof JPanel) 252 ) return parentContents; 253 panels = ((JPanel)panels[0]).getComponents(); 254 if (panels.length != 2 || 255 !(panels[0] instanceof JPanel) || 256 !(panels[1] instanceof JPanel) 257 ) return parentContents; 258 panels = ((JPanel)panels[0]).getComponents(); 259 if (panels.length != 2 || 260 !(panels[0] instanceof JLabel) || 261 !(panels[1] instanceof JPanel) 262 ) return parentContents; 263 panels = ((JPanel)panels[1]).getComponents(); 264 if (panels.length != 2 || 265 !(panels[0] instanceof JTextField) || 266 !(panels[1] instanceof JButton) 267 ) return parentContents; 268 JTextField fileComponent = (JTextField)panels[0]; 269 JButton fileButton = (JButton)panels[1]; 270 McVGuiUtils.setButtonImage(fileButton, ICON_OPEN_SMALL); 271 McVGuiUtils.setComponentWidth(fileButton, Width.DOUBLE); 272 McVGuiUtils.setComponentHeight(fileComponent, fileButton); 273 274 // Rearrange the sounding selector and assign it to innerPanel 275 JPanel innerPanel = doMakeInnerPanel((JPanel)parentComps[1]); 276 277 // Assign sounding selector loadButton to the chooser 278 JPanel bottomPanel = (JPanel)parentComps[2]; 279 Component[] buttons = bottomPanel.getComponents(); 280 281 // Dig down through all the GuiUtils parents 282 buttons = ((JPanel)buttons[1]).getComponents(); 283 buttons = ((JPanel)buttons[1]).getComponents(); 284 buttons = ((JPanel)buttons[0]).getComponents(); 285 buttons = ((JPanel)buttons[0]).getComponents(); 286 287 for (Component button : buttons) { 288 if (button instanceof JButton && 289 ((JButton)button).getText() == getLoadCommandName()) { 290 loadButton = (JButton)button; 291 break; 292 } 293 } 294 if (loadButton==null) return parentContents; 295 296 statusLabel.setEnabled(false); 297 setStatus("Status unavailable"); 298 299 // Start building the whole thing here 300 JPanel outerPanel = new JPanel(); 301 302 JLabel fileLabel = McVGuiUtils.makeLabelRight("File:"); 303 304 JLabel statusLabelLabel = McVGuiUtils.makeLabelRight(""); 305 306 McVGuiUtils.setLabelPosition(statusLabel, Position.RIGHT); 307 McVGuiUtils.setComponentColor(statusLabel, TextColor.STATUS); 308 309 JButton helpButton = McVGuiUtils.makeImageButton(ICON_HELP, "Show help"); 310 helpButton.setActionCommand(GuiUtils.CMD_HELP); 311 helpButton.addActionListener(this); 312 313 JButton refreshButton = McVGuiUtils.makeImageButton(ICON_REFRESH, "Refresh"); 314 refreshButton.setActionCommand(GuiUtils.CMD_UPDATE); 315 refreshButton.addActionListener(this); 316 317 McVGuiUtils.setButtonImage(loadButton, ICON_ACCEPT_SMALL); 318 McVGuiUtils.setComponentWidth(loadButton, Width.DOUBLE); 319 320 GroupLayout layout = new GroupLayout(outerPanel); 321 outerPanel.setLayout(layout); 322 layout.setHorizontalGroup( 323 layout.createParallelGroup(LEADING) 324 .addGroup(TRAILING, layout.createSequentialGroup() 325 .addGroup(layout.createParallelGroup(TRAILING) 326 .addGroup(layout.createSequentialGroup() 327 .addContainerGap() 328 .addComponent(helpButton) 329 .addGap(GAP_RELATED) 330 .addComponent(refreshButton) 331 .addPreferredGap(RELATED) 332 .addComponent(loadButton)) 333 .addGroup(LEADING, layout.createSequentialGroup() 334 .addContainerGap() 335 .addGroup(layout.createParallelGroup(LEADING) 336 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 337 .addGroup(layout.createSequentialGroup() 338 .addComponent(fileLabel) 339 .addGap(GAP_RELATED) 340 .addComponent(fileComponent) 341 .addGap(GAP_UNRELATED) 342 .addComponent(fileButton)) 343 .addGroup(layout.createSequentialGroup() 344 .addComponent(statusLabelLabel) 345 .addGap(GAP_RELATED) 346 .addComponent(statusLabel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))))) 347 .addContainerGap()) 348 ); 349 layout.setVerticalGroup( 350 layout.createParallelGroup(LEADING) 351 .addGroup(layout.createSequentialGroup() 352 .addContainerGap() 353 .addGroup(layout.createParallelGroup(BASELINE) 354 .addComponent(fileLabel) 355 .addComponent(fileComponent) 356 .addComponent(fileButton)) 357 .addPreferredGap(UNRELATED) 358 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 359 .addPreferredGap(UNRELATED) 360 .addGroup(layout.createParallelGroup(BASELINE) 361 .addComponent(statusLabelLabel) 362 .addComponent(statusLabel)) 363 .addPreferredGap(UNRELATED) 364 .addGroup(layout.createParallelGroup(BASELINE) 365 .addComponent(loadButton) 366 .addComponent(refreshButton) 367 .addComponent(helpButton)) 368 .addContainerGap()) 369 ); 370 371 return outerPanel; 372 373 } 374 375} 376