001 /* 002 * $Id: FrameChooser.java,v 1.8 2012/02/19 17:35:36 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 034 import ucar.unidata.idv.*; 035 036 import ucar.unidata.ui.ChooserList; 037 import ucar.unidata.ui.ChooserPanel; 038 039 import java.awt.*; 040 import java.awt.event.*; 041 042 import java.util.Vector; 043 044 import java.beans.*; 045 046 import javax.swing.*; 047 import javax.swing.border.*; 048 import javax.swing.event.*; 049 050 import ucar.unidata.util.GuiUtils; 051 import ucar.unidata.util.Misc; 052 import ucar.unidata.util.PreferenceList; 053 054 /** 055 * 056 * @author Unidata IDV Development Team 057 * @version $Revision: 1.8 $ 058 */ 059 public abstract class FrameChooser extends ChooserPanel { 060 061 /** Property for new data selection */ 062 public static String NEW_SELECTION = "FrameChooser.NEW_SELECTION"; 063 064 /** Have connected */ 065 protected static final int STATE_CONNECTED = 2; 066 067 /** flag for ignoring combobox changes */ 068 protected boolean ignoreStateChangedEvents = false; 069 070 /** 071 * Public keys for frame numbers, request, and data name. 072 */ 073 public final static String FRAME_NUMBERS_KEY = "frame numbers"; 074 public final static String DATA_NAME_KEY = "data name"; 075 public final static String REQUEST_HOST = "host"; 076 public final static String REQUEST_PORT = "port"; 077 public final static String REQUEST_KEY = "key"; 078 079 /** Used to synchronize access to widgets (eg: disabling, setting state, etc). */ 080 protected Object WIDGET_MUTEX = new Object(); 081 082 /** frames list */ 083 private ChooserList framesList; 084 085 /** Keep track of when are are doing a frame loop */ 086 private boolean doLoop = false; 087 088 /** Frame loop radio button */ 089 private JRadioButton loopRB; 090 091 /** Refresh current frame radio button */ 092 private JRadioButton curRB; 093 094 /** 095 * Create me. 096 */ 097 public FrameChooser() {} 098 099 /** 100 * Handle when the user presses the update button 101 * 102 * @throws Exception _more_ 103 */ 104 public void handleUpdate() throws Exception {} 105 106 /** 107 * Handle when the user presses the update button 108 */ 109 public void handleUpdateFromThread() { 110 showWaitCursor(); 111 try { 112 handleUpdate(); 113 } catch (Exception exc) { 114 } 115 showNormalCursor(); 116 } 117 118 /** 119 * Update the selector. Call handleUpdate in a thread 120 */ 121 public final void doUpdate() { 122 Misc.run(this, "handleUpdateFromThread"); 123 } 124 125 /** 126 * Handle the event 127 * 128 * @param ae The event 129 */ 130 public void actionPerformed(ActionEvent ae) { 131 String cmd = ae.getActionCommand(); 132 super.actionPerformed(ae); 133 } 134 135 /** 136 * Disable/enable any components that depend on the server. 137 * Try to update the status labelwith what we know here. 138 */ 139 protected void updateStatus() { 140 setHaveData(getGoodToGo()); 141 } 142 143 /** 144 * Are there any times in the times list. 145 * 146 * @return Do we have any times at all. 147 */ 148 protected boolean haveAnyTimes() { 149 return framesList.getModel().getSize() > 0; 150 } 151 152 /** 153 * Are there more than one times in the times list. 154 * 155 * @return Do we have a series. 156 */ 157 protected boolean haveASeries() { 158 Object[] selectedTimes = getTimesList().getSelectedValues(); 159 return selectedTimes.length > 1; 160 } 161 162 /** 163 * Create (if needed) and return the list that shows frames. 164 * 165 * @return The frames list. 166 */ 167 public ChooserList getTimesList() { 168 if (framesList == null) { 169 framesList = new ChooserList(); 170 framesList.setVisibleRowCount(getTimesListSize()); 171 framesList.addListSelectionListener(new ListSelectionListener() { 172 public void valueChanged(ListSelectionEvent e) { 173 updateStatus(); 174 } 175 }); 176 } 177 return framesList; 178 } 179 180 /** 181 * Get the size of the times list 182 * 183 * @return the times list size 184 */ 185 protected int getTimesListSize() { 186 return 6; 187 } 188 189 /** 190 * Clear all times in the times list. 191 */ 192 protected void clearFramesList() { 193 getTimesList().setListData(new Vector()); 194 } 195 196 /** 197 * Do what needs to be done to read in the times. Subclasses 198 * need to implement this. 199 */ 200 protected abstract void readFrames(); 201 202 /** 203 * Are we all set to load data. 204 * 205 * @return All set to load. 206 */ 207 protected boolean getGoodToGo() { 208 if ( !haveFrameSelected()) { 209 return false; 210 } 211 return true; 212 } 213 214 /** 215 * Create the current frame / frame loop selector 216 * 217 * @return the image list panel 218 */ 219 protected JPanel makeFramesPanel() { 220 221 getTimesList().addListSelectionListener(new ListSelectionListener() { 222 public void valueChanged(ListSelectionEvent e) { 223 if ( !getDoFrameLoop()) { 224 return; 225 } 226 } 227 }); 228 229 ChangeListener listener = new ChangeListener() { 230 public void stateChanged(ChangeEvent ae) { 231 if (loopRB.isSelected() == getDoFrameLoop()) { 232 return; 233 } 234 doLoop = loopRB.isSelected(); 235 if (doLoop && !haveAnyTimes()) { 236 readFrames(); 237 } else { 238 updateStatus(); 239 } 240 enableWidgets(); 241 } 242 }; 243 244 loopRB = new JRadioButton("Select frames", getDoFrameLoop()); 245 loopRB.addChangeListener(listener); 246 curRB = new JRadioButton("Refresh current frame", !getDoFrameLoop()); 247 curRB.addChangeListener(listener); 248 GuiUtils.buttonGroup(loopRB, curRB); 249 JPanel panel = GuiUtils.doLayout(new Component[] { 250 curRB, loopRB, 251 new JLabel(" "),getTimesList().getScroller() 252 }, 2, GuiUtils.WT_N, GuiUtils.WT_NY); 253 return GuiUtils.wrap(panel); 254 } 255 256 /** 257 * Are there any frames selected. 258 * 259 * @return Any frames selected. 260 */ 261 protected boolean haveFrameSelected() { 262 return !getDoFrameLoop() || getTimesList().haveDataSelected(); 263 } 264 265 /** 266 * Do we do a frame loop or refresh current frame 267 * 268 * @return Do we do frame loop 269 */ 270 protected boolean getDoFrameLoop() { 271 return doLoop; 272 } 273 274 /** 275 * Set whether we do a frame loop or refresh current frame 276 * 277 * @param yesorno true to do frame loop 278 */ 279 protected void setDoFrameLoop(boolean yesorno) { 280 doLoop = yesorno; 281 // Should this be in 282 if (curRB != null) { 283 curRB.setSelected(yesorno); 284 } 285 } 286 287 /** 288 * Did the user select current frame? 289 * 290 * @return Should we load current frame 291 */ 292 protected boolean getDoCurrentFrame() { 293 return !getDoFrameLoop(); 294 } 295 296 /** 297 * Enable or disable the GUI widgets based on what has been 298 * selected. 299 */ 300 protected void enableWidgets() { 301 getTimesList().setEnabled(getDoFrameLoop()); 302 } 303 }