001 /*
002 * $Id: UrlChooser.java,v 1.10 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.Alignment.BASELINE;
035 import static javax.swing.GroupLayout.Alignment.LEADING;
036 import static javax.swing.GroupLayout.Alignment.TRAILING;
037 import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
038 import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED;
039
040 import java.awt.event.ActionEvent;
041 import java.awt.event.ActionListener;
042 import java.awt.event.KeyEvent;
043 import java.awt.event.KeyListener;
044 import java.util.Hashtable;
045 import java.util.List;
046
047 import javax.swing.GroupLayout;
048 import javax.swing.JButton;
049 import javax.swing.JComboBox;
050 import javax.swing.JComponent;
051 import javax.swing.JLabel;
052 import javax.swing.JPanel;
053 import javax.swing.JRadioButton;
054 import javax.swing.JScrollPane;
055 import javax.swing.JTextArea;
056 import javax.swing.JTextField;
057
058 import org.w3c.dom.Element;
059
060 import edu.wisc.ssec.mcidasv.Constants;
061 import edu.wisc.ssec.mcidasv.util.McVGuiUtils;
062 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Position;
063 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.TextColor;
064 import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width;
065
066 import ucar.unidata.data.DataManager;
067 import ucar.unidata.idv.IntegratedDataViewer;
068 import ucar.unidata.idv.chooser.IdvChooserManager;
069 import ucar.unidata.util.GuiUtils;
070 import ucar.unidata.util.PreferenceList;
071 import ucar.unidata.util.StringUtil;
072
073 /**
074 * Allows the user to select a url as a data source
075 *
076 * @author IDV development team
077 * @version $Revision: 1.10 $Date: 2012/02/19 17:35:37 $
078 */
079
080
081 public class UrlChooser extends ucar.unidata.idv.chooser.UrlChooser implements Constants {
082
083 /** Manages the pull down list of urls */
084 private PreferenceList prefList;
085
086 /** The list of urls */
087 private JComboBox box;
088 private JTextField boxEditor;
089
090 /** The text area for multi-line urls */
091 private JTextArea textArea;
092
093 /** text scroller */
094 private JScrollPane textScroller;
095
096 /** Holds the combo box */
097 private JPanel urlPanel;
098
099 /** Holds the text area */
100 private JPanel textPanel;
101
102 /** Are we showing the combo box */
103 private boolean showBox = true;
104
105 /** Swtich */
106 private JButton switchBtn;
107
108 /** panel */
109 private GuiUtils.CardLayoutPanel cardLayoutPanel;
110
111 /**
112 * Get a handle on the IDV
113 */
114 protected IntegratedDataViewer idv = getIdv();
115
116 /**
117 * Create the <code>UrlChooser</code>
118 *
119 * @param mgr The <code>IdvChooserManager</code>
120 * @param root The xml root that defines this chooser
121 *
122 */
123 public UrlChooser(IdvChooserManager mgr, Element root) {
124 super(mgr, root);
125
126 loadButton = McVGuiUtils.makeImageTextButton(ICON_ACCEPT_SMALL, getLoadCommandName());
127 loadButton.setActionCommand(getLoadCommandName());
128 loadButton.addActionListener(this);
129
130 }
131
132 /**
133 * toggle the combobox with the text area
134 */
135 public void switchFields() {
136 if (showBox) {
137 cardLayoutPanel.show(urlPanel);
138 } else {
139 cardLayoutPanel.show(textPanel);
140 }
141 updateStatus();
142 }
143
144 /**
145 * Disable/enable any components that depend on the server.
146 * Try to update the status label with what we know here.
147 */
148 protected void updateStatus() {
149 if (boxEditor==null || textArea==null) return;
150 if (showBox) {
151 if (!boxEditor.getText().trim().equals(""))
152 setHaveData(true);
153 else
154 setHaveData(false);
155 } else {
156 if (!textArea.getText().trim().equals(""))
157 setHaveData(true);
158 else
159 setHaveData(false);
160 }
161 super.updateStatus();
162 if (!getHaveData()) {
163 if (showBox) setStatus("Enter a URL");
164 else setStatus("Enter one or more URLs");
165 }
166 }
167
168 /**
169 * Handle the action event from the GUI
170 */
171 @Override public void doLoadInThread() {
172 loadURL();
173 }
174
175 /**
176 * Wrapper around {@see #loadURLInner()}, showing the wait cursor
177 */
178 private void loadURL() {
179 showWaitCursor();
180 loadURLInner();
181 showNormalCursor();
182 }
183
184 /**
185 * Load the URL.
186 */
187 private void loadURLInner() {
188
189 String url = "";
190 String dataSourceId = getDataSourceId();
191 if (showBox) {
192 Object selectedItem = box.getSelectedItem();
193 if (selectedItem != null) {
194 url = selectedItem.toString().trim();
195 }
196 if (url.length() == 0 && dataSourceId == null) {
197 userMessage("Please specify a url");
198 return;
199 }
200 }
201
202 Hashtable properties = new Hashtable();
203 if (dataSourceId != null) {
204 properties.put(DataManager.DATATYPE_ID, dataSourceId);
205 }
206
207 if (showBox) {
208 if (idv.handleAction(url, properties)) {
209 closeChooser();
210 prefList.saveState(box);
211 }
212 } else {
213 List urls = StringUtil.split(textArea.getText(), "\n", true,
214 true);
215
216 if ((urls.size() > 0)
217 && makeDataSource(urls, dataSourceId, properties)) {
218 closeChooser();
219 }
220 }
221 }
222
223 /**
224 * Make the contents
225 *
226 * @return the contents
227 */
228 protected JPanel doMakeInnerPanel() {
229 JRadioButton singleBtn = new JRadioButton("Single", true);
230 JRadioButton multipleBtn = new JRadioButton("Multiple", false);
231 singleBtn.addActionListener(new ActionListener() {
232 public void actionPerformed(ActionEvent e) {
233 showBox = true;
234 switchFields();
235 }
236 });
237 multipleBtn.addActionListener(new ActionListener() {
238 public void actionPerformed(ActionEvent e) {
239 showBox = false;
240 switchFields();
241 }
242 });
243 GuiUtils.buttonGroup(singleBtn, multipleBtn);
244 JPanel radioPanel = GuiUtils.hbox(singleBtn, multipleBtn);
245
246 prefList = getPreferenceList(PREF_URLLIST);
247 box = prefList.createComboBox(CMD_LOAD, this);
248 boxEditor = (JTextField)box.getEditor().getEditorComponent();
249 boxEditor.addKeyListener(new KeyListener() {
250 public void keyPressed(KeyEvent e) {}
251 public void keyReleased(KeyEvent e) {
252 updateStatus();
253 }
254 public void keyTyped(KeyEvent e) {}
255 });
256
257 textArea = new JTextArea(5, 30);
258 textScroller = new JScrollPane(textArea);
259 textArea.addKeyListener(new KeyListener() {
260 public void keyPressed(KeyEvent e) {}
261 public void keyReleased(KeyEvent e) {
262 updateStatus();
263 }
264 public void keyTyped(KeyEvent e) {}
265 });
266
267 urlPanel = GuiUtils.top(box);
268 textPanel = GuiUtils.top(textScroller);
269
270 cardLayoutPanel = new GuiUtils.CardLayoutPanel();
271 cardLayoutPanel.addCard(urlPanel);
272 cardLayoutPanel.addCard(textPanel);
273
274 JPanel showPanel = McVGuiUtils.topBottom(radioPanel, cardLayoutPanel, null);
275
276 setHaveData(false);
277 updateStatus();
278 return McVGuiUtils.makeLabeledComponent("URL:", showPanel);
279 }
280
281 private JLabel statusLabel = new JLabel("Status");
282
283 @Override
284 public void setStatus(String statusString, String foo) {
285 if (statusString == null)
286 statusString = "";
287 statusLabel.setText(statusString);
288 }
289
290 /**
291 * Create a more McIDAS-V-like GUI layout
292 */
293 protected JComponent doMakeContents() {
294 JComponent typeComponent = getDataSourcesComponent();
295 if (typeComponent==null) typeComponent=new JLabel("No data type specified");
296
297 JPanel innerPanel = doMakeInnerPanel();
298
299 // Start building the whole thing here
300 JPanel outerPanel = new JPanel();
301
302 JLabel typeLabel = McVGuiUtils.makeLabelRight("Data Type:");
303
304 JLabel statusLabelLabel = McVGuiUtils.makeLabelRight("");
305
306 statusLabel.setText("Status");
307 McVGuiUtils.setLabelPosition(statusLabel, Position.RIGHT);
308 McVGuiUtils.setComponentColor(statusLabel, TextColor.STATUS);
309
310 JButton helpButton = McVGuiUtils.makeImageButton(ICON_HELP, "Show help");
311 helpButton.setActionCommand(GuiUtils.CMD_HELP);
312 helpButton.addActionListener(this);
313
314 JButton refreshButton = McVGuiUtils.makeImageButton(ICON_REFRESH, "Refresh");
315 refreshButton.setActionCommand(GuiUtils.CMD_UPDATE);
316 refreshButton.addActionListener(this);
317
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(typeLabel)
339 .addGap(GAP_RELATED)
340 .addComponent(typeComponent))
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(typeLabel)
353 .addComponent(typeComponent))
354 .addPreferredGap(UNRELATED)
355 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)
356 .addPreferredGap(UNRELATED)
357 .addGroup(layout.createParallelGroup(BASELINE)
358 .addComponent(statusLabelLabel)
359 .addComponent(statusLabel))
360 .addPreferredGap(UNRELATED)
361 .addGroup(layout.createParallelGroup(BASELINE)
362 .addComponent(loadButton)
363 .addComponent(refreshButton)
364 .addComponent(helpButton))
365 .addContainerGap())
366 );
367
368 return outerPanel;
369
370 }
371
372 }
373