001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.gui.util;
020:
021: import java.awt.event.FocusEvent;
022: import java.awt.event.FocusListener;
023: import java.awt.event.KeyAdapter;
024: import java.awt.event.KeyEvent;
025: import java.text.DateFormat;
026: import java.text.ParseException;
027: import java.text.SimpleDateFormat;
028: import java.util.Calendar;
029: import java.util.Date;
030:
031: import javax.swing.JTextField;
032:
033: /**
034: * This is Date mask control. Using this control we can pop up our date in the
035: * text field. And this control is Devloped basically for JDK1.3 and lower
036: * version support. This control is similer to JSpinner control this is
037: * available in JDK1.4 and above only.
038: * <p>
039: * This will set the date "yyyy/MM/dd HH:mm:ss" in this format only.
040: * </p>
041: *
042: */
043: public class JDateField extends JTextField {
044:
045: // Datefields are not thread-safe
046: private final DateFormat dateFormat = new SimpleDateFormat(
047: "yyyy/MM/dd HH:mm:ss"); // $NON-NLS-1$
048:
049: /*
050: * The following array must agree with dateFormat
051: *
052: * It is used to translate the positions in the buffer to the values used by
053: * the Calendar class for the field id.
054: *
055: * Current format: MM/DD/YYYY HH:MM:SS 01234567890123456789 ^buffer
056: * positions
057: */
058: private static int fieldPositions[] = { Calendar.YEAR, // Y
059: Calendar.YEAR, // Y
060: Calendar.YEAR, // Y
061: Calendar.YEAR, // Y
062: Calendar.YEAR, // sp
063: Calendar.MONTH, // M
064: Calendar.MONTH, // M
065: Calendar.MONTH, // /
066: Calendar.DAY_OF_MONTH, // D
067: Calendar.DAY_OF_MONTH, // D
068: Calendar.DAY_OF_MONTH, // /
069: Calendar.HOUR_OF_DAY, // H
070: Calendar.HOUR_OF_DAY, // H
071: Calendar.HOUR_OF_DAY, // :
072: Calendar.MINUTE, // M
073: Calendar.MINUTE, // M
074: Calendar.MINUTE, // :
075: Calendar.SECOND, // S
076: Calendar.SECOND, // S
077: Calendar.SECOND // end
078: };
079:
080: /**
081: * Create a DateField with the specified date.
082: */
083: public JDateField(Date date) {
084: super (20);
085: this .addKeyListener(new KeyFocus());
086: this .addFocusListener(new FocusClass());
087: String myString = dateFormat.format(date);
088: setText(myString);
089: }
090:
091: // Dummy constructor to allo JUnit tests to work
092: public JDateField() {
093: this (new Date());
094: }
095:
096: /**
097: * Set the date to the Date mask control.
098: */
099: public void setDate(Date date) {
100: setText(dateFormat.format(date));
101: }
102:
103: /**
104: * Get the date from the Date mask control.
105: */
106: public Date getDate() {
107: try {
108: return dateFormat.parse(getText());
109: } catch (ParseException e) {
110: return new Date();
111: } catch (Exception e) {
112: // DateFormat.parse has some bugs (up to JDK 1.4.2) by which it
113: // throws unchecked exceptions. E.g. see:
114: // http://developer.java.sun.com/developer/bugParade/bugs/4699765.html
115: //
116: // To avoid problems with such situations, we'll catch all
117: // exceptions here and act just as for ParseException above:
118: return new Date();
119: }
120: }
121:
122: /*
123: * Convert position in buffer to Calendar type Assumes that pos >=0 (which
124: * is true for getCaretPosition())
125: */
126: private static int posToField(int pos) {
127: if (pos >= fieldPositions.length) { // if beyond the end
128: pos = fieldPositions.length - 1; // then set to the end
129: }
130: return fieldPositions[pos];
131: }
132:
133: /**
134: * Converts a date/time to a calendar using the defined format
135: */
136: private Calendar parseDate(String datetime) {
137: Calendar c = Calendar.getInstance();
138: try {
139: Date dat = dateFormat.parse(datetime);
140: c.setTime(dat);
141: } catch (ParseException e) {
142: // Do nothing; the current time will be returned
143: }
144: return c;
145: }
146:
147: /*
148: * Update the current field. The addend is only expected to be +1/-1, but
149: * other values will work. N.B. the roll() method only supports changes by a
150: * single unit - up or down
151: */
152: private void update(int addend, boolean shifted) {
153: Calendar c = parseDate(getText());
154: int pos = getCaretPosition();
155: int field = posToField(pos);
156: if (shifted) {
157: c.roll(field, true);
158: } else {
159: c.add(field, addend);
160: }
161: String newDate = dateFormat.format(c.getTime());
162: setText(newDate);
163: if (pos > newDate.length())
164: pos = newDate.length();
165: setCaretPosition(pos);// Restore position
166:
167: }
168:
169: class KeyFocus extends KeyAdapter {
170: KeyFocus() {
171: }
172:
173: public void keyPressed(KeyEvent e) {
174: if (e.getKeyCode() == KeyEvent.VK_UP) {
175: update(1, e.isShiftDown());
176: } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
177: update(-1, e.isShiftDown());
178: }
179: }
180: }
181:
182: class FocusClass implements FocusListener {
183: FocusClass() {
184: }
185:
186: public void focusGained(FocusEvent e) {
187: }
188:
189: public void focusLost(FocusEvent e) {
190: try {
191: dateFormat.parse(getText());
192: } catch (ParseException e1) {
193: requestFocus();
194: }
195: }
196: }
197: }
|