View Javadoc

1   /*
2    * Copyright (c) 2006 Stiftung Deutsches Elektronen-Synchroton,
3    * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
4    *
5    * THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS.
6    * WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
7    * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND
8    * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
9    * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10   * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
11   * THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE
12   * IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR
13   * CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
14   * NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
15   * DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
16   * OR MODIFICATIONS.
17   * THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION,
18   * USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS
19   * PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY
20   * AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM
21   */
22  
23  package de.desy.acop.displayers;
24  
25  import java.beans.PropertyVetoException;
26  import java.util.Map;
27  
28  import javax.swing.Action;
29  
30  import com.cosylab.gui.InfoDialog;
31  import com.cosylab.gui.SliderDisplayer;
32  import com.cosylab.gui.components.SliderSetMode;
33  import com.cosylab.gui.components.util.IconHelper;
34  import com.cosylab.gui.displayers.DataConsumer;
35  import com.cosylab.gui.displayers.DataState;
36  import com.cosylab.gui.displayers.DisplayerUtilities;
37  import com.cosylab.gui.displayers.DoubleConsumer;
38  import com.cosylab.gui.displayers.DoubleConsumerMulticaster;
39  import com.cosylab.gui.displayers.DoubleSeqConsumer;
40  import com.cosylab.gui.util.UserSettingsProtection;
41  import com.cosylab.util.CommonException;
42  
43  import de.desy.acop.displayers.tools.AcopDisplayerTransferHandler;
44  import de.desy.acop.displayers.tools.AcopInfoDialog;
45  import de.desy.acop.displayers.tools.AcopDisplayer;
46  import de.desy.acop.launcher.Launcher;
47  import de.desy.acop.transport.ConnectionParameters;
48  import de.desy.acop.transport.adapters.AcopTransportDataSource;
49  import de.desy.acop.transport.adapters.AdapterFactory;
50  import de.desy.acop.transport.adapters.AdapterFactoryService;
51  import de.desy.tine.definitions.TArrayType;
52  
53  /**
54   * <code>AcopSlider</code> is a displayer which can show a single 
55   * double value. The slider can be used as a component which controls
56   * settable connection points.
57   * <p>
58   * The component consists of a JSlider which has a user interface 
59   * is sensitive to mouse movement. User can set a value by dragging the 
60   * thumb of the JSlider. The thumb will always show the value that the
61   * user has set. A black trailer on the same slider will show the actual 
62   * value that is read from the remote property. The position of the trailer
63   * cannot be set in runtime.
64   * </p>
65   * <p>
66   * Value on AcopSlider can also be adjusted using the navigation buttons
67   * or the number field on the top of the component. By setting the properties
68   * {@link #setBitStep(double)}, {@link #setSmallStep(double)} and 
69   * {@link #setLargeStep(double)} one can configure the size of the steps used
70   * when pressing the navigations buttons. If using the number field the
71   * value has to be confirmed by pressing enter key before it results in the 
72   * movement of the thumb.
73   * </p>
74   * <p>
75   * Slider has three different types of set modes (see {@link SliderSetMode}) which
76   * specify at what actions the set value will be sent to the remote connection point.
77   * </p>
78   * <p>
79   * The connection point for this displayer should be set using the 
80   * <i>connectionParameters</i> property, where the remote name of the 
81   * {@link ConnectionParameters} points to the desired property.
82   * </p>
83   * 
84   * 
85   * @author <a href="mailto:jaka.bobnar@cosylab.com">Jaka Bobnar</a>
86   * @version $Id: Templates.xml,v 1.10 2004/01/13 16:17:13 jbobnar Exp $
87   *
88   */
89  public class AcopSlider extends SliderDisplayer implements DoubleSeqConsumer,  
90  	AcopDisplayer {
91  	 
92  	public static void main(String[] args) {
93  		
94  		Launcher.launch(AcopSlider.class, args, true);
95  		
96  	}
97  	
98  	private static final long serialVersionUID = -2503329416853153653L;
99  	private ConnectionParameters connectionParameters;
100 	private int arrayIndex=0;
101 	private AcopInfoDialog dialog;
102 
103 	/**
104 	 * Constructs new AcopSlider.
105 	 *
106 	 */
107 	public AcopSlider() {
108 		super();
109 		setRestoreButtonTitle("Old");
110 		setStorageButtonsVisible(true);
111 		setAcopIcons();
112 		setContinuousControlVisible(true);
113 		new AcopDisplayerTransferHandler(this);
114 		UserSettingsProtection.setProtection(this,DisplayerUtilities.COMMON_NUMERIC_DISPLAYER_PROPERTIES,false);		
115 	}
116 	
117 	/**
118 	 * Apply navigation button icons demanded by ACOP
119 	 * 
120 	 * bitDecrement button uses ArrowLeft.gif instead of Minus16.gif
121 	 * bitIncrement button uses ArrowRight.gif instead of Plus16.gif
122 	 * slowDecrement button uses ArrowLeftLeft.gif instead of ArrowLeftLeft.gif
123 	 * slowIncrement button uses ArrowRightRight.gif instead of
124 	 * ArrowRightRight.gif fastDecrement button uses ArrowLeftLeftLeft.gif
125 	 * instead of ArrowLeftLeft.gif fastIncrement button uses
126 	 * ArrowRightRightRight.gif instead of ArrowRightRight.gif
127 	 * 
128 	 */
129 	public void setAcopIcons() {
130 		setButtonIcon(Button.BIT_DECREMENT, IconHelper.createIcon("icons/navigation/ArrowLeft16.gif"));
131 		setButtonIcon(Button.BIT_INCREMENT, IconHelper.createIcon("icons/navigation/ArrowRight16.gif"));
132 
133 		setButtonIcon(Button.SLOW_DECREMENT, IconHelper.createIcon("icons/navigation/ArrowLeftLeft16.gif"));
134 		setButtonIcon(Button.SLOW_INCREMENT, IconHelper.createIcon("icons/navigation/ArrowRightRight16.gif"));
135 
136 		setButtonIcon(Button.FAST_DECREMENT, IconHelper.createIcon("icons/navigation/ArrowLeftLeftLeft16.gif"));
137 		setButtonIcon(Button.FAST_INCREMENT, IconHelper.createIcon("icons/navigation/ArrowRightRightRight16.gif"));
138 	}
139 
140 	/*
141 	 * (non-Javadoc)
142 	 * @see com.cosylab.gui.displayers.DoubleSeqConsumer#updateValue(long, double[])
143 	 */
144 	public void updateValue(long timestamp, double[] value) throws CommonException {
145 	    updateValue(timestamp, DisplayerUtilities.extract(arrayIndex,value));	
146     }
147 
148 	/* (non-Javadoc)
149 	 * @see com.cosylab.gui.displayers.DataConsumer#getDataConsumer(java.lang.Class)
150 	 */
151 	@Override
152 	public DataConsumer getDataConsumer(Class type)
153 	{
154 		if (type == DoubleConsumer.class || type == DoubleSeqConsumer.class) {
155 			return this;
156 		}
157 		
158 		return DoubleConsumerMulticaster.createDataConsumer(type, this);
159 	}
160 	
161 	/*
162 	 * (non-Javadoc)
163 	 * @see com.cosylab.gui.DialKnobDisplayer#setCharacteristics(java.util.Map)
164 	 */
165 	@Override
166 	public void setCharacteristics(Map characteristics) {
167 		super.setCharacteristics(characteristics);
168 		
169 		Object o  = characteristics.get("arrayType");
170 		if (o != null) {
171 			if (((TArrayType)o).isChannel()) {
172 				try {
173 					UserSettingsProtection.setUnprotected(this,"arrayIndex",0);
174 				} catch (Exception e) {
175 					e.printStackTrace();
176 				}
177 			}
178 		}
179 	}
180 	
181 	/*
182 	 * (non-Javadoc)
183 	 * @see de.desy.acop.displayers.AcopDisplayerConnector#getConnectionParameters()
184 	 */
185 	public ConnectionParameters getConnectionParameters() {
186 		return connectionParameters;
187 	}
188 	
189 	/*
190 	 * (non-Javadoc)
191 	 * @see de.desy.acop.displayers.AcopDisplayerConnector#setConnectionParameters(de.desy.acop.transport.ConnectionParameters)
192 	 */
193 	public void setConnectionParameters(ConnectionParameters param) throws CommonException, PropertyVetoException {
194 
195 		if (param!=null && connectionParameters != null) {
196 			if(param.equals(connectionParameters)) return;
197 		}
198 		updateDataState(new DataState(DataState.UNDEFINED));
199 			
200 		ConnectionParameters old = connectionParameters;
201 		this.connectionParameters = param;
202 		AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
203 		if (getDataSource() != null)
204 			factory.releaseDataSource((AcopTransportDataSource) getDataSource());
205 		if (param == null) {
206 			setDataSource(null);
207 			setTitle("No Connection");
208 		} else {
209 			if (param.getPropertySize() == ConnectionParameters.AUTO_PROPERTY_SIZE) {
210 				param = param.deriveWithPropertySize(1);
211 			}
212 			AcopTransportDataSource ds = factory.createDataSource(param);
213 			setDataSource(ds);
214 		}
215 		firePropertyChange(CONNECTION_PARAMETERS_PROPERTY,old, connectionParameters);
216 	}
217 
218 	/*
219 	 * (non-Javadoc)
220 	 * @see de.desy.acop.displayers.tools.AcopDisplayer#getArrayIndex()
221 	 */
222 	public int getArrayIndex() {
223 		return arrayIndex;
224 	}
225 
226 	/*
227 	 * (non-Javadoc)
228 	 * @see de.desy.acop.displayers.tools.AcopDisplayer#setArrayIndex(int)
229 	 */
230 	public void setArrayIndex(int arrayIndex) {
231 		if (this.arrayIndex == arrayIndex) return;
232 		int oldValue = this.arrayIndex;
233 		this.arrayIndex = arrayIndex;
234 		firePropertyChange("arrayIndex", oldValue, this.arrayIndex);
235 	}
236 
237 	/*
238 	 * (non-Javadoc)
239 	 * @see com.cosylab.gui.SliderDisplayer#getInfoDialog()
240 	 */
241 	@Override
242 	public InfoDialog getInfoDialog() {
243 		if (dialog == null) {
244 			dialog = new AcopInfoDialog(this);
245 		}
246 		return dialog;
247 	}
248 	
249 	/**
250 	 * Enables/disables Properties item in the popup menu.
251 	 * @param enable
252 	 */
253 	public void setPropertiesPopupEnabled(boolean enable) {
254 		Action[] actions = getPopupManager().getActions();
255 		for (Action a : actions) {
256 			if (a != null && "Preferences...".equals(a.getValue(Action.NAME))) {
257 				a.setEnabled(enable);
258 				return;
259 			}
260 		}
261 	}
262 	
263 	/**
264 	 * Returns true if Properties item is enabled in the popup menu.
265 	 * @return
266 	 */
267 	public boolean isPropertiesPopupEnabled() {
268 		Action[] actions = getPopupManager().getActions();
269 		for (Action a : actions) {
270 			if (a != null && "Preferences...".equals(a.getValue(Action.NAME))) {
271 				return a.isEnabled();
272 			}
273 		}
274 		return false;
275 	}
276 }
277 
278 /* __oOo__ */