001: /*
002: * 02/02/2002 - 20:54:54
003: *
004: * JSpinField.java - A spin field similar to JSpinner in JDJ 1.4
005: * Copyright (C) 2002 Kai Toedter
006: * kai@toedter.com
007: * www.toedter.com
008: *
009: * This program is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public License
011: * as published by the Free Software Foundation; either version 2
012: * of the License, or (at your option) any later version.
013: *
014: * This program is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
017: * GNU Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public License
020: * along with this program; if not, write to the Free Software
021: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
022: */
023: package com.toedter.components;
024:
025: import java.awt.Adjustable;
026: import java.awt.BorderLayout;
027: import java.awt.Color;
028: import java.awt.Dimension;
029: import java.awt.Font;
030: import java.awt.event.ActionEvent;
031: import java.awt.event.ActionListener;
032: import java.awt.event.AdjustmentEvent;
033: import java.awt.event.AdjustmentListener;
034:
035: import javax.swing.JFrame;
036: import javax.swing.JPanel;
037: import javax.swing.JScrollBar;
038: import javax.swing.JTextField;
039: import javax.swing.event.CaretEvent;
040: import javax.swing.event.CaretListener;
041:
042: /**
043: * JSpinField is a numeric field with 2 spin buttons to increase or decrease
044: * the value.
045: *
046: *@author Kai Toedter
047: *@version 1.1.4 07/16/02
048: */
049: public class JSpinField extends JPanel implements CaretListener,
050: AdjustmentListener, ActionListener {
051: private static final long serialVersionUID = 3257009856274576438L;
052:
053: /**
054: * Default JSpinField constructor.
055: */
056: public JSpinField() {
057: super ();
058: min = 0;
059: max = 100;
060: value = 0;
061: darkGreen = new Color(0, 150, 0);
062:
063: setLayout(new BorderLayout());
064: textField = new JTextField(Integer.toString(value));
065: textField.addCaretListener(this );
066: textField.addActionListener(this );
067: textField.setHorizontalAlignment(JTextField.RIGHT);
068: add(textField, BorderLayout.CENTER);
069:
070: scrollBar = new JScrollBar(Adjustable.VERTICAL, 0, 0, 0, 100);
071: scrollBar.setPreferredSize(new Dimension(scrollBar
072: .getPreferredSize().width,
073: textField.getPreferredSize().height));
074: scrollBar.setMinimum(min);
075: scrollBar.setMaximum(max);
076: scrollBar.setValue(max + min - value);
077: scrollBar.setVisibleAmount(0);
078:
079: scrollBar.addAdjustmentListener(this );
080: add(scrollBar, BorderLayout.EAST);
081: }
082:
083: /**
084: * Sets the value attribute of the JSpinField object
085: *
086: *@param newValue The new value value
087: *@param updateTextField The new value value
088: *@param updateScrollbar The new value value
089: */
090: protected void setValue(int newValue, boolean updateTextField,
091: boolean updateScrollbar) {
092: int oldValue = value;
093:
094: if (newValue < min) {
095: value = min;
096: } else if (newValue > max) {
097: value = max;
098: } else {
099: value = newValue;
100: }
101:
102: if (updateTextField) {
103: textField.setText(Integer.toString(value));
104: textField.setForeground(Color.black);
105: }
106:
107: if (updateScrollbar) {
108: scrollBar.setValue(max + min - value);
109: }
110:
111: firePropertyChange("value", oldValue, value);
112: }
113:
114: /**
115: * Sets the value. This is a bound property.
116: *
117: *@param newValue the new value
118: *@see #getValue
119: */
120: public void setValue(int newValue) {
121: setValue(newValue, true, true);
122: }
123:
124: /**
125: * Returns the value.
126: *
127: *@return The value value
128: */
129: public int getValue() {
130: return value;
131: }
132:
133: /**
134: * Sets the minimum value.
135: *
136: *@param newMinimum the new minimum value
137: *@see #getMinimum
138: */
139: public void setMinimum(int newMinimum) {
140: min = newMinimum;
141: scrollBar.setMinimum(min);
142: }
143:
144: /**
145: * Returns the minimum value.
146: *
147: *@return The minimum value
148: */
149: public int getMinimum() {
150: return min;
151: }
152:
153: /**
154: * Sets the maximum value and adjusts the preferred width.
155: *
156: *@param newMaximum the new maximum value
157: *@see #getMaximum
158: */
159: public void setMaximum(int newMaximum) {
160: max = newMaximum;
161: scrollBar.setMaximum(max);
162:
163: textField.setPreferredSize(new Dimension(new JTextField(Integer
164: .toString(newMaximum)).getPreferredSize().width,
165: textField.getPreferredSize().height));
166: }
167:
168: /**
169: * Sets the horizontal alignment of the displayed value.
170: */
171: public void setHorizontalAlignment(int alignment) {
172: textField.setHorizontalAlignment(alignment);
173: }
174:
175: /**
176: * Returns the maximum value.
177: *
178: *@return The maximum value
179: */
180: public int getMaximum() {
181: return max;
182: }
183:
184: /**
185: * Sets the font property.
186: *
187: *@param font the new font
188: */
189: public void setFont(Font font) {
190: if (textField != null) {
191: textField.setFont(font);
192: }
193: }
194:
195: /**
196: * Sets the foreground color.
197: *
198: *@param fg the new foreground
199: */
200: public void setForeground(Color fg) {
201: if (textField != null) {
202: textField.setForeground(fg);
203: }
204: }
205:
206: /**
207: * After any user input, the value of the textfield is proofed. Depending on
208: * being an integer, the value is colored green or red.
209: *
210: *@param e Description of the Parameter
211: */
212: public void caretUpdate(CaretEvent e) {
213: try {
214: int testValue = Integer.valueOf(textField.getText())
215: .intValue();
216:
217: if ((testValue >= min) && (testValue <= max)) {
218: textField.setForeground(darkGreen);
219: setValue(testValue, false, false);
220: } else {
221: textField.setForeground(Color.red);
222: }
223: } catch (Exception ex) {
224: if (ex instanceof NumberFormatException) {
225: textField.setForeground(Color.red);
226: }
227: // Ignore all other exceptions, e.g. illegal state exception
228: }
229: textField.repaint();
230: }
231:
232: /**
233: * The 2 buttons are implemented with a JScrollBar.
234: *
235: *@param e Description of the Parameter
236: */
237: public void adjustmentValueChanged(AdjustmentEvent e) {
238: setValue(max + min - e.getValue(), true, false);
239: }
240:
241: /**
242: * After any user input, the value of the textfield is proofed. Depending on
243: * being an integer, the value is colored green or red. If the textfield is
244: * green, the enter key is accepted and the new value is set.
245: *
246: *@param e Description of the Parameter
247: */
248: public void actionPerformed(ActionEvent e) {
249: if (textField.getForeground().equals(darkGreen)) {
250: setValue(Integer.valueOf(textField.getText()).intValue());
251: }
252: }
253:
254: /**
255: * Enable or disable the JSpinField.
256: *
257: *@param enabled The new enabled value
258: */
259: public void setEnabled(boolean enabled) {
260: super .setEnabled(enabled);
261: textField.setEnabled(enabled);
262: scrollBar.setEnabled(enabled);
263: }
264:
265: /**
266: * Creates a JFrame with a JSpinField inside and can be used for testing.
267: *
268: *@param s The command line arguments
269: */
270: public static void main(String[] s) {
271: JFrame frame = new JFrame("JSpinField");
272: frame.getContentPane().add(new JSpinField());
273: frame.pack();
274: frame.setVisible(true);
275: }
276:
277: /**
278: * the text (number) field
279: */
280: protected JTextField textField;
281: /**
282: * the scrollbar for the spin buttons
283: */
284: protected JScrollBar scrollBar;
285: private Color darkGreen;
286: private int min;
287: private int max;
288: private int value;
289: }
|