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