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