001 /*
002 * $Id: RaobChooser.java,v 1.12 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.Color;
042 import java.awt.Component;
043 import java.awt.Dimension;
044
045 import javax.swing.GroupLayout;
046 import javax.swing.JButton;
047 import javax.swing.JComponent;
048 import javax.swing.JLabel;
049 import javax.swing.JPanel;
050 import javax.swing.JScrollPane;
051 import javax.swing.JTextField;
052
053 import org.w3c.dom.Element;
054
055 import ucar.unidata.idv.chooser.IdvChooserManager;
056 import ucar.unidata.util.GuiUtils;
057 import ucar.unidata.xml.XmlUtil;
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 /**
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.12 $Date: 2012/02/19 17:35:37 $
073 */
074
075
076 public 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