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.chart;
24  
25  import java.awt.Dimension;
26  import java.awt.GridBagConstraints;
27  import java.awt.GridBagLayout;
28  import java.awt.Insets;
29  import java.awt.event.ActionEvent;
30  import java.awt.event.ActionListener;
31  import java.awt.event.KeyAdapter;
32  import java.awt.event.KeyEvent;
33  
34  import javax.swing.JButton;
35  import javax.swing.JLabel;
36  import javax.swing.JPanel;
37  import javax.swing.JTextField;
38  
39  import com.cosylab.gui.components.numberfield.DoubleDocument;
40  
41  import de.desy.acop.displayers.tools.AcopUtilities;
42  
43  /**
44   * <code>MinMaxPanel</code> provides a user interface through which minimum
45   * and maximum values can be entered. When values are entered into the field
46   * the actual properties of this panel are not change until the user
47   * presses the <i>Apply</i> button.
48   * 
49   * @author <a href="mailto:jaka.bobnar@cosylab.com">Jaka Bobnar</a>
50   * @version $Id: Templates.xml,v 1.10 2004/01/13 16:17:13 jbobnar Exp $
51   *
52   */
53  public class MinMaxPanel extends JPanel {
54  		
55  	private static final long serialVersionUID = 1L;
56  
57  	private JButton rescaleButton;
58  	
59  	private JTextField maxField;
60  	private JTextField minField;
61  	private DoubleDocument maxDocument;
62  	private DoubleDocument minDocument;
63  	private JLabel maxLabel;
64  	private JLabel minLabel;
65  	private double min = 0;
66  	private double max = 0;
67  	private Dimension fieldDim = new Dimension(70,21); 
68  	private boolean rescaleEnabled = false;
69  	private boolean extraDigits = false;
70  	private boolean useScientific = true;
71  	
72  	
73  	/**
74  	 * Creates a new MinMaxPanel.
75  	 *
76  	 */
77  	public MinMaxPanel() {
78  		super();
79  		initialize();
80  	}
81  	
82  	private void initialize() {
83  		setLayout(new GridBagLayout());	
84  		
85  		maxField = new JTextField();
86  		maxDocument = new DoubleDocument();
87  		maxField.setDocument(maxDocument);
88  		maxField.setText(String.valueOf(max));
89  		maxField.addKeyListener(new KeyAdapter() {
90  			public void keyPressed(KeyEvent evt) {
91  				rescaleEnabled = true;
92  				rescaleButton.setEnabled(isEnabled());
93  			}
94  		});
95  		
96  		maxField.setMinimumSize(fieldDim);
97  		maxField.setPreferredSize(fieldDim);
98  		maxField.setToolTipText("Maximum Value");
99  		
100 		maxLabel = new JLabel("Max");
101 		this.add(maxField, new GridBagConstraints(1,0,1,1,1,0,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0,2,2,0),0,0));
102 		this.add(maxLabel, new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,2,2),0,0));
103 		
104 		minField = new JTextField();
105 		minDocument = new DoubleDocument();
106 		minField.setDocument(minDocument);
107 		minField.setText(String.valueOf(min));
108 		minField.addKeyListener(new KeyAdapter() {
109 			public void keyPressed(KeyEvent evt) {
110 				rescaleEnabled = true;
111 				rescaleButton.setEnabled(isEnabled());
112 			}
113 		});
114 		minField.setMinimumSize(fieldDim);
115 		minField.setPreferredSize(fieldDim);
116 		minField.setToolTipText("Minimum Value");
117 		
118 		minLabel = new JLabel("Min");
119 		this.add(minField, new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2,2,2,0),0,0));
120 		this.add(minLabel, new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,2,2,2),0,0));
121 		
122 		rescaleButton = new JButton("Apply Scale");
123 		rescaleButton.addActionListener(new ActionListener(){
124 			public void actionPerformed(ActionEvent e) {
125 				rescaleEnabled = false;
126 				setMin(minDocument.getValue().doubleValue());
127 				setMax(maxDocument.getValue().doubleValue());
128 				rescaleButton.setEnabled(false);
129 			}
130 		});
131 		rescaleButton.setEnabled(false);
132 		rescaleButton.setToolTipText("Apply New Scale Settings");
133 		rescaleButton.setEnabled(false);
134 		
135 		this.add(rescaleButton, new GridBagConstraints(0,2,2,1,1,0,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2,0,0,0),0,0));
136 	}
137 	
138 	/**
139 	 * Returns the maximum value.
140 	 * @return the max value
141 	 */
142 	public double getMax() {
143 		return max;
144 	}
145 
146 	/**
147 	 * Sets maximum value and fires property change event.
148 	 * 
149 	 * @param max new maximum value
150 	 */
151 	public void setMax(double max) {
152 		setMax(max, true);
153 	}
154 	
155 	/**
156 	 * Sets new maximum value and fires a property change event if requested.
157 	 * 
158 	 * @param max new maximum value
159 	 * @param notify should property change event be triggered
160 	 */
161 	public void setMax(double max, boolean notify) {
162 		if (this.max == max) return;
163 		double oldValue = this.max;
164 		this.max = max;
165 		applyMax(max);
166 		if (notify) {
167 			firePropertyChange("max", oldValue, this.max);
168 		}
169 	}
170 		
171 	private void applyMax(double max) {
172 		boolean enabled = maxField.isEnabled();
173 		maxField.setEnabled(true);
174 		maxField.setText(AcopUtilities.formatValue(max, extraDigits));
175 		maxField.setEnabled(enabled);
176 		maxField.setCaretPosition(0);
177 	}
178 	
179 	/**
180 	 * Returns the minimum value.
181 	 * @return the minimum value
182 	 */
183 	public double getMin() {
184 		return min;
185 	}
186 
187 	/**
188 	 * Sets the minimum and fires property change event.
189 	 * 
190 	 * @param min new minimum
191 	 */
192 	public void setMin(double min) {
193 		setMin(min, true);
194 	}
195 	
196 	/**
197 	 * Sets new minimum value and fires a property change event if requested.
198 	 * 
199 	 * @param min new minimum value
200 	 * @param notify should property change event be triggered
201 	 */
202 	public void setMin(double min, boolean notify) {
203 		if (this.min == min) return;
204 		double oldValue = this.min;
205 		this.min = min;
206 		applyMin(min);
207 		if (notify) {
208 			firePropertyChange("min", oldValue, this.min);
209 		}
210 	}
211 	
212 	private void applyMin(double min) {
213 		boolean enabled = minField.isEnabled();
214 		minField.setEnabled(true);
215 		minField.setText(AcopUtilities.formatValue(min, extraDigits));
216 		minField.setEnabled(enabled);
217 		minField.setCaretPosition(0);
218 	}
219 	
220 	/**
221 	 * Sets the apply button enabled/disabled.
222 	 * 
223 	 * @param enabled
224 	 */
225 	public void setRescaleEnabled(boolean enabled) {
226 		if (enabled == rescaleEnabled) return;
227 		this.rescaleEnabled = enabled;
228 		rescaleButton.setEnabled(enabled & isEnabled());
229 		firePropertyChange("rescaleEnabled", !enabled, enabled);
230 	}
231 	
232 	/**
233 	 * Returns true if the apply button is enabled.
234 	 * 
235 	 * @return the state of the apply button
236 	 */
237 	public boolean isRescaleEnabled() {
238 		return rescaleEnabled;
239 	}
240 
241 	/*
242 	 * (non-Javadoc)
243 	 * @see javax.swing.JComponent#setEnabled(boolean)
244 	 */
245 	@Override
246 	public void setEnabled(boolean enabled) {
247 		super.setEnabled(enabled);
248 		minField.setEnabled(enabled);
249 		maxField.setEnabled(enabled);
250 		minLabel.setEnabled(enabled);
251 		maxLabel.setEnabled(enabled);
252 		rescaleButton.setEnabled(enabled & rescaleEnabled);
253 	}
254 	
255 	/**
256 	 * Sets the flag of extra digits. If extra digits is turned on 6-decimal
257 	 * format is used, otherwise 2-decimal format is used.
258 	 * 
259 	 * @param extraDigits
260 	 */
261 	public void setExtraDigits(boolean extraDigits) {
262 		if (this.extraDigits == extraDigits) return;
263 		this.extraDigits = extraDigits;
264 		firePropertyChange("extraDigits", !extraDigits, extraDigits);
265 		applyMax(max);
266 		applyMin(min);
267 	}
268 	
269 	/**
270 	 * Returns true if extra digits flag is true.
271 	 * 
272 	 * @return
273 	 */
274 	public boolean isExtraDigits() {
275 		return extraDigits;
276 	}
277 	
278 	/**
279 	 * If scientific is set to true, the value will be formatted using
280 	 * a scientific exponential format if value is less than 1e-2 or 
281 	 * greater or equal than 1e4.
282 	 * @param scientific
283 	 */
284 	public void setUseScientific(boolean scientific) {
285 		if (this.useScientific == scientific) return;
286 		this.useScientific = scientific;
287 		firePropertyChange("useScientific", !scientific, scientific);
288 		applyMax(max);
289 		applyMin(min);
290 	}
291 	
292 	/**
293 	 * Returns true if scientific formatting is used.
294 	 * @return
295 	 */
296 	public boolean isUseScientific() {
297 		return useScientific;
298 	}
299 }