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