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