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