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