1 /* JFormattedTextField.java --
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java
.awt
.event
.FocusEvent
;
42 import java
.io
.Serializable
;
43 import java
.text
.Format
;
44 import java
.text
.ParseException
;
45 import java
.util
.Date
;
47 import javax
.swing
.text
.DateFormatter
;
48 import javax
.swing
.text
.DefaultFormatter
;
49 import javax
.swing
.text
.Document
;
50 import javax
.swing
.text
.DocumentFilter
;
51 import javax
.swing
.text
.NavigationFilter
;
54 * A text field that makes use of a formatter to display and edit a specific
55 * type of data. The value that is displayed can be an arbitrary object. The
56 * formatter is responsible for displaying the value in a textual form and
57 * it may allow editing of the value.
59 * Formatters are usually obtained using an instance of
60 * {@link AbstractFormatterFactory}. This factory is responsible for providing
61 * an instance of {@link AbstractFormatter} that is able to handle the
62 * formatting of the value of the JFormattedTextField.
64 * @author Michael Koch
68 public class JFormattedTextField
extends JTextField
70 private static final long serialVersionUID
= 5464657870110180632L;
73 * An abstract base implementation for a formatter that can be used by
74 * a JTextField. A formatter can display a specific type of object and
75 * may provide a way to edit this value.
77 public abstract static class AbstractFormatter
implements Serializable
79 private static final long serialVersionUID
= -5193212041738979680L;
81 private JFormattedTextField textField
;
83 public AbstractFormatter ()
88 protected Object
clone ()
89 throws CloneNotSupportedException
91 throw new InternalError ("not implemented");
94 protected Action
[] getActions ()
96 return textField
.getActions();
99 protected DocumentFilter
getDocumentFilter ()
101 throw new InternalError ("not implemented");
104 protected JFormattedTextField
getFormattedTextField ()
109 protected NavigationFilter
getNavigationFilter ()
111 return textField
.getNavigationFilter();
114 public void install(JFormattedTextField textField
)
116 if (this.textField
!= null)
119 this.textField
= textField
;
122 public void uninstall ()
124 this.textField
= null;
127 protected void invalidEdit ()
129 textField
.invalidEdit();
132 protected void setEditValid (boolean valid
)
134 textField
.editValid
= valid
;
137 public abstract Object
stringToValue (String text
)
138 throws ParseException
;
140 public abstract String
valueToString (Object value
)
141 throws ParseException
;
145 * Delivers instances of an {@link AbstractFormatter} for
146 * a specific value type for a JFormattedTextField.
148 public abstract static class AbstractFormatterFactory
150 public AbstractFormatterFactory ()
155 public abstract AbstractFormatter
getFormatter (JFormattedTextField tf
);
158 static class FormatterFactoryWrapper
extends AbstractFormatterFactory
160 AbstractFormatter formatter
;
162 public FormatterFactoryWrapper(AbstractFormatter formatter
)
164 this.formatter
= formatter
;
167 public AbstractFormatter
getFormatter(JFormattedTextField tf
)
173 public static final int COMMIT
= 0;
174 public static final int COMMIT_OR_REVERT
= 1;
175 public static final int REVERT
= 2;
176 public static final int PERSIST
= 3;
178 private Object value
;
179 private int focusLostBehavior
= COMMIT_OR_REVERT
;
180 private AbstractFormatterFactory formatterFactory
;
181 // Package-private to avoid an accessor method.
182 boolean editValid
= true;
184 public JFormattedTextField ()
186 this((AbstractFormatterFactory
) null, null);
189 public JFormattedTextField (Format format
)
191 throw new InternalError ("not implemented");
194 public JFormattedTextField (AbstractFormatter formatter
)
196 this(new FormatterFactoryWrapper(formatter
), null);
199 public JFormattedTextField (AbstractFormatterFactory factory
)
204 public JFormattedTextField (AbstractFormatterFactory factory
, Object value
)
206 this.formatterFactory
= factory
;
210 public JFormattedTextField (Object value
)
215 public void commitEdit ()
216 throws ParseException
218 throw new InternalError ("not implemented");
221 public Action
[] getActions ()
223 // FIXME: Add JFormattedTextField specific actions
224 return super.getActions();
227 public int getFocusLostBehavior()
229 return focusLostBehavior
;
232 public AbstractFormatter
getFormatter ()
234 if (formatterFactory
== null)
237 return formatterFactory
.getFormatter(this);
240 public AbstractFormatterFactory
getFormatterFactory ()
242 return formatterFactory
;
245 public String
getUIClassID ()
247 return "FormattedTextFieldUI";
250 public Object
getValue ()
255 protected void invalidEdit ()
257 UIManager
.getLookAndFeel().provideErrorFeedback(this);
260 public boolean isEditValid ()
265 protected void processFocusEvent (FocusEvent evt
)
267 // it's safe to simply call super for now, until it gets clear
268 // what this method is supposed to do
269 // throw new InternalError ("not implemented");
270 super.processFocusEvent(evt
);
273 public void setDocument(Document newDocument
)
275 Document oldDocument
= getDocument();
277 if (oldDocument
== newDocument
)
280 super.setDocument(newDocument
);
283 public void setFocusLostBehavior(int behavior
)
285 if (behavior
!= COMMIT
286 && behavior
!= COMMIT_OR_REVERT
287 && behavior
!= PERSIST
288 && behavior
!= REVERT
)
289 throw new IllegalArgumentException("invalid behavior");
291 this.focusLostBehavior
= behavior
;
294 protected void setFormatter (AbstractFormatter formatter
)
296 AbstractFormatter oldFormatter
= null;
298 if (formatterFactory
!= null)
299 oldFormatter
= formatterFactory
.getFormatter(this);
301 if (oldFormatter
== formatter
)
304 setFormatterFactory(new FormatterFactoryWrapper(formatter
));
305 firePropertyChange("formatter", oldFormatter
, formatter
);
308 public void setFormatterFactory (AbstractFormatterFactory factory
)
310 if (formatterFactory
== factory
)
313 AbstractFormatterFactory oldFactory
= formatterFactory
;
314 formatterFactory
= factory
;
315 firePropertyChange("formatterFactory", oldFactory
, factory
);
318 public void setValue (Object newValue
)
320 if (value
== newValue
)
324 AbstractFormatter formatter
= createFormatter(newValue
);
327 setText(formatter
.valueToString(newValue
));
329 catch (ParseException ex
)
331 // TODO: what should we do with this?
334 Object oldValue
= value
;
336 firePropertyChange("value", oldValue
, newValue
);
340 * A helper method that attempts to create a formatter that is suitable
341 * to format objects of the type like <code>value</code>.
343 * If <code>formatterFactory</code> is not null and the returned formatter
344 * is also not <code>null</code> then this formatter is used. Otherwise we
345 * try to create one based on the type of <code>value</code>.
347 * @param value an object which should be formatted by the formatter
349 * @return a formatter able to format objects of the class of
352 AbstractFormatter
createFormatter(Object value
)
354 AbstractFormatter formatter
= null;
355 if (formatterFactory
!= null
356 && formatterFactory
.getFormatter(this) != null)
357 formatter
= formatterFactory
.getFormatter(this);
360 if (value
instanceof Date
)
361 formatter
= new DateFormatter();
363 formatter
= new DefaultFormatter();