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.selector;
24  
25  import java.awt.Dimension;
26  import java.awt.GridBagConstraints;
27  import java.awt.GridBagLayout;
28  import java.awt.Insets;
29  import java.beans.Customizer;
30  import java.beans.PropertyChangeEvent;
31  import java.beans.PropertyChangeListener;
32  
33  import javax.swing.JLabel;
34  import javax.swing.JPanel;
35  import javax.swing.JSlider;
36  import javax.swing.JSpinner;
37  import javax.swing.SpinnerNumberModel;
38  import javax.swing.event.ChangeEvent;
39  import javax.swing.event.ChangeListener;
40  
41  import com.cosylab.gui.components.util.RunnerHelper;
42  
43  import de.desy.acop.displayers.tools.AcopDisplayer;
44  import de.desy.acop.transport.ConnectionParameters;
45  
46  /**
47   * <code>ArrayIndexCustomizer</code> is a customizer which enables selection
48   * of a specific index in the array. When using spectrum properties on a single
49   * value displayers one can use this customizer to select a specific index which
50   * one wants to display on the widget. 
51   * <p>
52   * This component consist of a JSlider and JSpinner which allow selection of
53   * a specific index within the size of the property.
54   * </p>
55   * 
56   * @author <a href="mailto:jaka.bobnar@cosylab.com">Jaka Bobnar</a>
57   * @version $Id: Templates.xml,v 1.10 2004/01/13 16:17:13 jbobnar Exp $
58   *
59   */
60  public class ArrayIndexCustomizer extends JPanel implements Customizer{
61  	
62  	private static final long serialVersionUID = -401693602095711422L;
63  	private AcopDisplayer disp;
64  	private int arrayIndex = 0;
65  	private JSlider slider;
66  	private ConnectionParameters connectionParameters;
67  	private JSpinner spinner;
68  	private SpinnerNumberModel spinnerModel;
69  	private int lastValue = 0;
70  	
71  	/**
72  	 * Constructs a new ArrayIndexCustomizer.
73  	 *
74  	 */
75  	public ArrayIndexCustomizer() {
76  		super();
77  		initialize();
78  	}
79  	
80  	private void initialize() {
81  		this.setLayout(new GridBagLayout());
82  		add(new JLabel("Array index"), new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.EAST,GridBagConstraints.NONE,new Insets(4,11,4,4),0,0));
83  		add(getSpinner(), new GridBagConstraints(1,0,1,1,1,0,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(4,4,4,11),0,0));
84  		add(getSlider(), new GridBagConstraints(0,1,2,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(4,11,4,11),0,0));
85  
86  	}
87  	
88  	private JSlider getSlider() {
89  		if (slider == null) {
90  			slider = new JSlider();
91  	
92  			slider.setMinimum(0);
93  			slider.setValue(0);
94  			slider.setMaximum(100);
95  			slider.setMajorTickSpacing((int)Math.floor(100/4.0));
96  			slider.setMinorTickSpacing(1);
97  			slider.setPaintLabels(true);
98  			slider.setPaintTicks(true);
99  			slider.setPaintTrack(true);
100 			slider.setSnapToTicks(true);
101 			slider.addChangeListener(new ChangeListener() {
102 				
103 				public void stateChanged(ChangeEvent e) {
104 					//register only when value is changed, dont care about max/min
105 					if (slider.getValue() != lastValue) {
106 						lastValue = slider.getValue();
107 						setArrayIndex(lastValue);
108 						if (disp!=null) {
109 							disp.setArrayIndex(lastValue);
110 						}
111 						
112 					}
113 				}
114 			
115 			});
116 			
117 		}
118 		return slider;
119 	}
120 	
121 	private void refreshIndexList() {
122 		if (connectionParameters != null) {
123 			int length = connectionParameters.getPropertySize();
124 			if (length <= 0) {
125 				length = SelectorUtilities.getSequenceLength(connectionParameters);
126 			}
127 			if (length <= 1 || SelectorUtilities.isChannel(connectionParameters)) {
128 				slider.setEnabled(false);
129 				spinner.setEnabled(false);
130 				slider.setMaximum(1);
131 				spinnerModel.setMaximum(1);
132 			} else {
133 				slider.setEnabled(true);
134 				spinner.setEnabled(true);
135 				slider.setMaximum(length-1);
136 				spinnerModel.setMaximum(length-1);
137 				slider.setLabelTable(null);
138 				slider.setLabelTable(null);
139 				slider.setMajorTickSpacing((int)Math.floor(length/4.0));
140 			}
141 		} else {
142 			slider.setMaximum(1);
143 			spinnerModel.setMaximum(1);
144 			slider.setEnabled(false);
145 			spinner.setEnabled(false);
146 		}
147 	}
148 		
149 	/*
150 	 * (non-Javadoc)
151 	 * @see java.beans.Customizer#setObject(java.lang.Object)
152 	 */
153 	public void setObject(Object bean) {
154 		if (bean instanceof AcopDisplayer) {
155 			disp = (AcopDisplayer) bean;
156 			disp.addPropertyChangeListener("arrayIndex",
157 					new PropertyChangeListener(){
158 				public void propertyChange(PropertyChangeEvent evt) {
159 					setArrayIndex(disp.getArrayIndex());				
160 				}
161 			});
162 			disp.addPropertyChangeListener(AcopDisplayer.CONNECTION_PARAMETERS_PROPERTY,
163 					new PropertyChangeListener(){
164 				public void propertyChange(PropertyChangeEvent evt) {
165 					setConnectionParameters(disp.getConnectionParameters());
166 					setArrayIndex(disp.getArrayIndex());				
167 				}
168 			});
169 		} else {
170 			throw new IllegalArgumentException("Only AcopCommonDisplayer and" +
171 					" MultipleAcopDisplayer can use this Customizer.");
172 		}
173 		setConnectionParameters(disp.getConnectionParameters());
174 		setArrayIndex(disp.getArrayIndex());
175 	}
176 	
177 	/**
178 	 * Sets the selected array index.
179 	 * 
180 	 * @param index the selected index
181 	 */
182 	public void setArrayIndex(int index) {
183 		if (index == arrayIndex) return;
184 		int oldValue = arrayIndex;
185 		this.arrayIndex = index;
186 		getSlider().setValue(arrayIndex);
187 		getSpinner().setValue(arrayIndex);
188 		firePropertyChange("arrayIndex", oldValue, arrayIndex);
189 	}
190 	
191 	/**
192 	 * Returns the selected array index.
193 	 * 
194 	 * @return the selected index
195 	 */
196 	public int getArrayIndex() {
197 		return arrayIndex;
198 	}
199 	
200 	/**
201 	 * Sets the ConnectionParameters that points to the property, which index
202 	 * has to be selected for.
203 	 *   
204 	 * @param parameters remote connection point
205 	 */
206 	public void setConnectionParameters(ConnectionParameters parameters) {
207 		if (this.connectionParameters != null && this.connectionParameters.equals(parameters)) return;
208 		ConnectionParameters oldValue = this.connectionParameters;
209 		this.connectionParameters = parameters;
210 		refreshIndexList();
211 		firePropertyChange(AcopDisplayer.CONNECTION_PARAMETERS_PROPERTY, oldValue, this.connectionParameters);
212 	}
213 	
214 	/**
215 	 * Returns the ConnectionParameters that index is being selected for.
216 	 * 
217 	 * @return the connection parameters
218 	 */
219 	public ConnectionParameters getConnectionParameters() {
220 		return connectionParameters;
221 	}
222 	
223 	public static void main(String[] args) {
224 		RunnerHelper.runComponent(new ArrayIndexCustomizer(), 500, 420);
225 	}
226 
227 	
228 	/**
229 	 * Returns the spinner.
230 	 * @return Returns the spinner.
231 	 */
232 	private JSpinner getSpinner() {
233 		if (spinner==null) {
234 			spinner= new JSpinner();
235 			spinner.setMinimumSize(new Dimension(50,21));
236 			spinner.setPreferredSize(new Dimension(50,21));
237 			spinner.setModel(spinnerModel= new SpinnerNumberModel());
238 			spinnerModel.setStepSize(1);
239 			spinnerModel.setMinimum(0);
240 			spinnerModel.setMaximum(100);
241 			spinnerModel.addChangeListener(new ChangeListener() {
242 			
243 				public void stateChanged(ChangeEvent e) {
244 					getSlider().setValue(spinnerModel.getNumber().intValue());
245 				}
246 			
247 			});
248 		}
249 		return spinner;
250 	}
251 
252 }