001: package com.xoetrope.swing;
002:
003: import java.io.IOException;
004:
005: import java.awt.Color;
006:
007: import javax.swing.JSpinner;
008: import javax.swing.JTextField;
009: import javax.swing.SpinnerNumberModel;
010: import javax.swing.event.ChangeEvent;
011: import javax.swing.event.ChangeListener;
012: import net.xoetrope.swing.XEdit;
013:
014: import net.xoetrope.xui.XAttributedComponent;
015: import net.xoetrope.xui.XValueHolder;
016: import net.xoetrope.xui.events.XHandlerInvoker;
017: import net.xoetrope.xui.events.XListenerHelper;
018:
019: /**
020: * An Up-Down control or spin edit component
021: *
022: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
023: * the GNU Public License (GPL), please see license.txt for more details. If
024: * you make commercial use of this software you must purchase a commercial
025: * license from Xoetrope.</p>
026: * <p> $Revision: 1.14 $</p>
027: */
028: public class XSpinner extends JSpinner implements ChangeListener,
029: XAttributedComponent, XListenerHelper, XValueHolder {
030: protected SpinnerNumberModel spinnerModel;
031: private XHandlerInvoker invoker;
032:
033: public static final int SPINNER_TYPE_INT = 0;
034: public static final int SPINNER_TYPE_DOUBLE = 1;
035:
036: /**
037: * Create a new spinner
038: */
039: public XSpinner() {
040: initialize();
041: }
042:
043: private void initialize() {
044: spinnerModel = new SpinnerNumberModel(50, 1, 100, 1);
045: setModel(spinnerModel);
046: addChangeListener(this );
047: }
048:
049: /**
050: * Set the foreground color of the editor component
051: * @param c the new color
052: */
053: public void setForeground(Color c) {
054: JTextField textField = ((JSpinner.DefaultEditor) getEditor())
055: .getTextField();
056: textField.setForeground(c);
057: }
058:
059: /**
060: * Set the background color of the editor component
061: * @param c the new color
062: */
063: public void setBackground(Color c) {
064: JTextField textField = ((JSpinner.DefaultEditor) getEditor())
065: .getTextField();
066: textField.setBackground(c);
067: }
068:
069: /**
070: * Set an edit component to update
071: * @param je the component to update
072: */
073: public void setBuddy(XEdit je) {
074: buddyEdit = je;
075: }
076:
077: /**
078: * Set the spinner range
079: * @param min the max value
080: * @param max teh minimum value
081: */
082: public void setRange(int min, int max) {
083: spinnerModel.setMinimum(new Integer(min - 1));
084: // This is a complete hack, seems like something messed up in Swing or the JDK.
085: spinnerModel.setMaximum(new Integer(max + 11));
086: maxValue = max;
087: minValue = min;
088: value = Math.max(value, minValue);
089: value = Math.min(value, maxValue);
090: if (dataType == SPINNER_TYPE_INT)
091: spinnerModel.setValue(new Integer((int) value));
092: else
093: spinnerModel.setValue(new Double((double) value));
094: if (buddyEdit != null)
095: buddyEdit.setText(new Double(maxValue - value).toString());
096: spinnerModel.setStepSize(new Integer(1));
097: }
098:
099: /**
100: * The state changed
101: * @param e the state event
102: */
103: public void stateChanged(ChangeEvent e) {
104: if (bInAdjustment)
105: return;
106:
107: if ((invoker != null))
108: invoker.invoke();
109:
110: if (buddyEdit != null) {
111: double bv = new Double(buddyEdit.getText()).doubleValue();
112: double newValue = 0;
113: double newScrollValue = new Double(getValue().toString())
114: .doubleValue();
115: if (newScrollValue > value)
116: newValue = Math.max(minValue, --bv);
117: else if (newScrollValue < value)
118: newValue = Math.min(maxValue, ++bv);
119:
120: bInAdjustment = true;
121: buddyEdit.setText(new Double(newValue).toString());
122: value = newValue;
123: setValue(new Double(value));
124: bInAdjustment = false;
125: //buddyEdit.setValue( e.getValue() );
126: }
127: }
128:
129: /**
130: * Performs any post creation initialisation of the control.
131: * @throws java.io.IOException This component diesnt do any IO, but the exception is a boilerplate
132: */
133: public void init() throws IOException {
134: doLayout();
135: }
136:
137: /**
138: * Sets the value corresponding to the maximum value of the meter
139: * @param _value the new max value
140: */
141: public void setMax(double _value) {
142: spinnerModel.setMaximum(new Integer((int) _value));
143: maxValue = (int) _value;
144: }
145:
146: /**
147: * Sets the value corresponding to the minimum value of the meter
148: * @param _value the new min value
149: */
150: public void setMin(double _value) {
151: spinnerModel.setMinimum(new Integer((int) _value));
152: minValue = (int) _value;
153: }
154:
155: /**
156: * Sets the step size for the spinner
157: * @param _value the new step size
158: */
159: public void setStep(double _value) {
160: spinnerModel.setStepSize(new Double(_value));
161: stepSize = (int) _value;
162: }
163:
164: public void setDataType(String type) {
165: if (type.equals("int")) {
166: dataType = SPINNER_TYPE_INT;
167: spinnerModel.setValue(new Integer(String
168: .valueOf(spinnerModel.getValue())));
169: setEditor(new JSpinner.NumberEditor(this , "0"));
170: } else {
171: dataType = SPINNER_TYPE_DOUBLE;
172: //spinnerModel.setValue( new Double( String.valueOf( spinnerModel.getValue() ) ) );
173: double value = new Double(String.valueOf(spinnerModel
174: .getValue())).doubleValue();
175: double min = new Double(String.valueOf(spinnerModel
176: .getMinimum())).doubleValue();
177: double max = new Double(String.valueOf(spinnerModel
178: .getMaximum())).doubleValue();
179: double step = new Double(String.valueOf(spinnerModel
180: .getStepSize())).doubleValue();
181: spinnerModel = new SpinnerNumberModel(value, min, max,
182: stepSize);
183: setModel(spinnerModel);
184: //setEditor( new JSpinner.NumberEditor( this, "0.00" ) );
185: }
186: }
187:
188: /**
189: * Gets the value corresponding to the maximum value of the meter
190: * @return the max value
191: */
192: public double getMax() {
193: return maxValue;
194: }
195:
196: /**
197: * Gets the value corresponding to the minimum value of the meter
198: * @return the min value
199: */
200: public double getMin() {
201: return minValue;
202: }
203:
204: /**
205: * Gets the step size for the spinner
206: * @return the step size
207: */
208: public double getStep() {
209: return stepSize;
210: }
211:
212: /**
213: * Repaint the component once it has been created
214: */
215: public void addNotify() {
216: super .addNotify();
217: validate();
218: }
219:
220: /**
221: * Add a new event handler
222: * @param page the owner page
223: * @param type the event handler type
224: * @param methodName the method name
225: * @throws java.lang.NoSuchMethodException through if the method cannot be found
226: */
227: public void addHandler(Object page, String type, String methodName)
228: throws NoSuchMethodException {
229: invoker = new XHandlerInvoker(page, this , methodName);
230: }
231:
232: /**
233: * Set one or more attributes of the component.
234: * <OL>
235: * <LI>min, value=the minimum field value</LI>
236: * <LI>max, value=the maximum field value</LI>
237: * <LI>step, value=the field step size</LI>
238: * </OL>
239: * @param attribName the attribute name
240: * @param attribValue the attribute value
241: * @return 0 for success, non zero otherwise
242: */
243: public int setAttribute(String attribName, Object attribValue) {
244: String attribNameLwr = attribName.toLowerCase();
245: String attribValueStr = (String) attribValue;
246: if (attribNameLwr.equals("min")
247: || attribNameLwr.equals("minvalue"))
248: setMin(Double.parseDouble(attribValueStr));
249: else if (attribNameLwr.equals("max")
250: || attribNameLwr.equals("maxvalue"))
251: setMax(Double.parseDouble(attribValueStr));
252: else if (attribNameLwr.equals("step")
253: || attribNameLwr.equals("stepvalue"))
254: setStep(Double.parseDouble(attribValueStr));
255: else if (attribNameLwr.equals("datatype"))
256: setDataType(attribValueStr);
257: else if (attribNameLwr.equals("value"))
258: spinnerModel.setValue(new Double(attribValueStr));
259:
260: return 0;
261: }
262:
263: /**
264: * Get the object's value
265: * @return the value for this object
266: */
267: public Object getValue() {
268: if (spinnerModel != null)
269: return spinnerModel.getValue();
270: else
271: return null;
272: }
273:
274: /**
275: * Set the value associated with this component
276: * @param newValue the new object value
277: */
278: public void setValue(Object value) {
279: super .setValue(value);
280: }
281:
282: /**
283: * Get the text/label of the component
284: * @return the component's text
285: */
286: public void setText(String string) {
287: spinnerModel.setValue(new Double(string));
288: }
289:
290: /**
291: * Get the text/label of the component
292: * @return the component's text
293: */
294: public String getText() {
295: return null;
296: }
297:
298: private XEdit buddyEdit = null;
299: private double maxValue = 100;
300: private double minValue = 0;
301: private double value = 0;
302: private double stepSize = 1;
303: private int dataType;
304:
305: private static boolean bInAdjustment = false;
306: }
|