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: * @author Evgeniya G. Maenkova
019: * @version $Revision$
020: */package javax.swing.text;
021:
022: import java.awt.event.ActionEvent;
023: import java.text.AttributedCharacterIterator;
024: import java.text.Format;
025: import java.text.ParseException;
026: import java.util.Date;
027: import java.util.HashSet;
028: import java.util.Iterator;
029: import java.util.Set;
030: import javax.swing.Action;
031: import javax.swing.JFormattedTextField;
032: import javax.swing.JSpinner.DateEditor;
033:
034: import org.apache.harmony.awt.text.TextUtils;
035:
036: import org.apache.harmony.x.swing.internal.nls.Messages;
037:
038: public class InternationalFormatter extends DefaultFormatter {
039: private static final String DECREMENT_ACTION_NAME = "decrement";
040: private static final String INCREMENT_ACTION_NAME = "increment";
041: private Comparable max;
042: private Comparable min;
043: private Format format;
044: private static Action[] actions;
045:
046: static class IncrementAction extends TextAction {
047: private int increment;
048:
049: public IncrementAction(final String name, final int increment) {
050: super (name);
051: this .increment = increment;
052: }
053:
054: public void actionPerformed(final ActionEvent e) {
055: JTextComponent source = getTextComponent(e);
056: if (source instanceof JFormattedTextField) {
057: handleText((JFormattedTextField) source);
058: }
059: }
060:
061: private void handleText(final JFormattedTextField ftf) {
062: if (ftf.getFormatter() instanceof DateFormatter) {
063: try {
064: DateFormatter formatter = (DateFormatter) ftf
065: .getFormatter();
066: int calendarField = TextUtils.getCalendarField(ftf);
067: Date date = (Date) formatter.stringToValue(ftf
068: .getText());
069: date = increment > 0 ? (Date) TextUtils
070: .getNextValue(date, calendarField, null)
071: : (Date) TextUtils.getPreviousValue(date,
072: calendarField, null);
073: ftf.setText(formatter.valueToString(date));
074: TextUtils.selectCalendarField(ftf, calendarField);
075: } catch (ParseException e) {
076: e.printStackTrace();
077: }
078: }
079: }
080: }
081:
082: public InternationalFormatter() {
083: this (null);
084: }
085:
086: public InternationalFormatter(final Format format) {
087: this .format = format;
088: setOverwriteMode(false);
089: }
090:
091: public Object clone() throws CloneNotSupportedException {
092: return super .clone();
093: }
094:
095: public Format.Field[] getFields(final int offset) {
096: if (format == null) {
097: return null;
098: }
099:
100: Object value = getFormattedTextField().getValue();
101: if (value == null) {
102: return null;
103: }
104:
105: AttributedCharacterIterator iterator = format
106: .formatToCharacterIterator(value);
107: if (offset < iterator.getBeginIndex()
108: || offset > iterator.getEndIndex()) {
109: return new Format.Field[0];
110: }
111:
112: iterator.setIndex(offset);
113: Set keys = iterator.getAttributes().keySet();
114: Set result = new HashSet();
115: Iterator iter = keys.iterator();
116:
117: while (iter.hasNext()) {
118: Object key = iter.next();
119: if (key instanceof Format.Field) {
120: result.add(key);
121: }
122: }
123:
124: return (Format.Field[]) result.toArray(new Format.Field[result
125: .size()]);
126: }
127:
128: protected Action[] getActions() {
129: if (actions == null) {
130: actions = new TextAction[] {
131: new IncrementAction(INCREMENT_ACTION_NAME, 1),
132: new IncrementAction(DECREMENT_ACTION_NAME, -1) };
133: }
134: return (Action[]) actions.clone();
135: }
136:
137: public Format getFormat() {
138: return format;
139: }
140:
141: public Comparable getMaximum() {
142: return max;
143: }
144:
145: public Comparable getMinimum() {
146: return min;
147: }
148:
149: public void install(final JFormattedTextField ftf) {
150: super .install(ftf);
151: }
152:
153: public void setFormat(final Format format) {
154: this .format = format;
155: }
156:
157: public void setMaximum(final Comparable max) {
158: this .max = max;
159: if (max != null) {
160: setValueClass(max.getClass());
161: }
162: }
163:
164: public void setMinimum(final Comparable min) {
165: this .min = min;
166: if (min != null) {
167: setValueClass(min.getClass());
168: }
169: }
170:
171: public Object stringToValue(final String string)
172: throws ParseException {
173: if (string == null) {
174: return null;
175: }
176: Object result = null;
177: if (getValueClass() == null) {
178: result = format != null ? format.parseObject(string)
179: : string;
180: } else {
181: result = super .stringToValue(string);
182: }
183:
184: if (!checkRange(result)) {
185: throw new ParseException(Messages.getString("swing.8F"), 0); //$NON-NLS-1$
186: }
187: return result;
188: }
189:
190: private boolean checkRange(final Object value) {
191: boolean result = false;
192: try {
193: result = (min == null || min.compareTo(value) <= 0)
194: && (max == null || max.compareTo(value) >= 0);
195: } catch (ClassCastException e) {
196:
197: }
198: return result;
199: }
200:
201: public String valueToString(final Object value)
202: throws ParseException {
203: if (value == null) {
204: return "";
205: } else {
206: return format != null ? format.format(value) : value
207: .toString();
208: }
209: }
210:
211: final String getFormattedText(final String text) {
212: Object value = null;
213: try {
214: value = stringToValue(text);
215: } catch (ParseException e) {
216: }
217: if (value == null) {
218: return "";
219: }
220:
221: return (format != null) ? format.format(value) : text;
222: }
223: }
|