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