2 Copyright (C) 2002, 2004, 2005 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
.Dimension
;
43 import java
.awt
.FontMetrics
;
44 import java
.awt
.event
.ActionEvent
;
45 import java
.awt
.event
.ActionListener
;
46 import java
.beans
.PropertyChangeEvent
;
47 import java
.beans
.PropertyChangeListener
;
49 import javax
.accessibility
.AccessibleContext
;
50 import javax
.accessibility
.AccessibleStateSet
;
51 import javax
.swing
.text
.Document
;
52 import javax
.swing
.text
.JTextComponent
;
53 import javax
.swing
.text
.PlainDocument
;
54 import javax
.swing
.text
.TextAction
;
56 public class JTextField
extends JTextComponent
57 implements SwingConstants
60 * AccessibleJTextField
62 protected class AccessibleJTextField
extends AccessibleJTextComponent
64 private static final long serialVersionUID
= 8255147276740453036L;
67 * Constructor AccessibleJTextField
69 protected AccessibleJTextField()
75 * Returns the accessible state of this <code>AccessibleJTextField</code>.
77 * @return the accessible state of this <code>AccessibleJTextField</code>
79 public AccessibleStateSet
getAccessibleStateSet()
81 AccessibleStateSet state
= super.getAccessibleStateSet();
82 // TODO: Figure out what state must be added here to the super's state.
87 private static final long serialVersionUID
= 353853209832607592L;
89 private static final Action
[] actions
;
92 * Name of the action that gets sent when the content of the text field
95 public static final String notifyAction
= "notify-field-accept";
99 actions
= new Action
[1];
100 actions
[0] = new TextAction(notifyAction
)
102 public void actionPerformed(ActionEvent event
)
104 JTextField textField
= (JTextField
) event
.getSource();
105 textField
.fireActionPerformed();
112 private int scrollOffset
;
115 private Action action
;
118 private String actionCommand
;
120 private PropertyChangeListener actionPropertyChangeListener
;
123 * The horizontal visibility of the textfield.
125 private BoundedRangeModel horizontalVisibility
;
128 * Creates a new instance of <code>JTextField</code>.
136 * Creates a new instance of <code>JTextField</code>.
138 * @param text the initial text
140 public JTextField(String text
)
146 * Creates a new instance of <code>JTextField</code>.
148 * @param columns the number of columns
150 * @exception IllegalArgumentException if columns %lt; 0
152 public JTextField(int columns
)
154 this(null, null, columns
);
158 * Creates a new instance of <code>JTextField</code>.
160 * @param text the initial text
161 * @param columns the number of columns
163 * @exception IllegalArgumentException if columns %lt; 0
165 public JTextField(String text
, int columns
)
167 this(null, text
, columns
);
171 * Creates a new instance of <code>JTextField</code>.
173 * @param doc the document to use
174 * @param text the initial text
175 * @param columns the number of columns
177 * @exception IllegalArgumentException if columns %lt; 0
179 public JTextField(Document doc
, String text
, int columns
)
182 throw new IllegalArgumentException();
184 this.columns
= columns
;
186 setDocument(doc
== null ?
createDefaultModel() : doc
);
191 // default value for alignment
194 // Initialize the horizontal visibility model.
195 horizontalVisibility
= new DefaultBoundedRangeModel();
199 * Creates the default model for this text field.
200 * This implementation returns an instance of <code>PlainDocument</code>.
202 * @return a new instance of the default model
204 protected Document
createDefaultModel()
206 PlainDocument doc
= new PlainDocument();
207 doc
.putProperty("filterNewlines", Boolean
.TRUE
);
212 * Returns the class ID for the UI.
214 * @return "TextFieldUI";
216 public String
getUIClassID()
218 return "TextFieldUI";
222 * Adds a new listener object to this text field.
224 * @param listener the listener to add
226 public void addActionListener(ActionListener listener
)
228 listenerList
.add(ActionListener
.class, listener
);
232 * Removes a listener object from this text field.
234 * @param listener the listener to remove
236 public void removeActionListener(ActionListener listener
)
238 listenerList
.remove(ActionListener
.class, listener
);
242 * Returns all registered <code>ActionListener</code> objects.
244 * @return an array of listeners
248 public ActionListener
[] getActionListeners()
250 return (ActionListener
[]) getListeners(ActionListener
.class);
254 * Sends an action event to all registered
255 * <code>ActionListener</code> objects.
257 protected void fireActionPerformed()
259 ActionEvent event
= new ActionEvent(this, 0, notifyAction
);
260 ActionListener
[] listeners
= getActionListeners();
262 for (int index
= 0; index
< listeners
.length
; ++index
)
263 listeners
[index
].actionPerformed(event
);
267 * Returns the number of columns of this text field.
269 * @return the number of columns
271 public int getColumns()
277 * Sets the number of columns and then invalidates the layout.
278 * @param columns the number of columns
279 * @throws IllegalArgumentException if columns < 0
281 public void setColumns(int columns
)
284 throw new IllegalArgumentException();
286 this.columns
= columns
;
288 //FIXME: do we need this repaint call?
293 * Returns the horizontal alignment, which is one of: JTextField.LEFT,
294 * JTextField.CENTER, JTextField.RIGHT, JTextField.LEADING,
295 * JTextField.TRAILING.
296 * @return the horizontal alignment
298 public int getHorizontalAlignment()
304 * Sets the horizontal alignment of the text. Calls invalidate and repaint
305 * and fires a property change event.
306 * @param newAlign must be one of: JTextField.LEFT, JTextField.CENTER,
307 * JTextField.RIGHT, JTextField.LEADING, JTextField.TRAILING.
308 * @throws IllegalArgumentException if newAlign is not one of the above.
310 public void setHorizontalAlignment(int newAlign
)
312 //FIXME: should throw an IllegalArgumentException if newAlign is invalid
313 if (align
== newAlign
)
316 int oldAlign
= align
;
318 firePropertyChange("horizontalAlignment", oldAlign
, newAlign
);
324 * Sets the current font and revalidates so the font will take effect.
326 public void setFont(Font newFont
)
328 super.setFont(newFont
);
333 * Returns the preferred size. If there is a non-zero number of columns,
334 * this is the number of columns multiplied by the column width, otherwise
335 * it returns super.getPreferredSize().
337 public Dimension
getPreferredSize()
339 Dimension size
= super.getPreferredSize();
342 size
.width
= columns
* getColumnWidth();
348 * Returns the scroll offset in pixels.
350 * @return the scroll offset
352 public int getScrollOffset()
354 //FIXME: this should return horizontalVisibility's value
359 * Sets the scroll offset in pixels.
361 * @param offset the scroll offset
363 public void setScrollOffset(int offset
)
365 //FIXME: this should actualy scroll the field if needed
366 scrollOffset
= offset
;
370 * Returns the set of Actions that are commands for the editor.
371 * This is the actions supported by this editor plus the actions
372 * of the UI (returned by JTextComponent.getActions()).
374 public Action
[] getActions()
376 return TextAction
.augmentList(super.getActions(), actions
);
379 public void postActionEvent()
381 String command
= actionCommand
!= null ? actionCommand
: getText();
382 ActionEvent event
= new ActionEvent(this, 0, command
);
383 ActionListener
[] listeners
= getActionListeners();
385 for (int index
= 0; index
< listeners
.length
; ++index
)
386 listeners
[index
].actionPerformed(event
);
392 public Action
getAction()
400 public void setAction(Action newAction
)
402 if (action
== newAction
)
407 removeActionListener(action
);
408 action
.removePropertyChangeListener(actionPropertyChangeListener
);
409 actionPropertyChangeListener
= null;
412 Action oldAction
= action
;
417 addActionListener(action
);
418 actionPropertyChangeListener
= createActionPropertyChangeListener(action
);
419 action
.addPropertyChangeListener(actionPropertyChangeListener
);
422 //FIXME: is this a hack? The horizontal alignment hasn't changed
423 firePropertyChange("horizontalAlignment", oldAction
, newAction
);
427 * Sets the command string used in action events.
430 public void setActionCommand(String command
)
432 actionCommand
= command
;
438 protected PropertyChangeListener
createActionPropertyChangeListener(Action action
)
440 return new PropertyChangeListener()
442 public void propertyChange(PropertyChangeEvent event
)
444 // Update properties "action" and "horizontalAlignment".
445 String name
= event
.getPropertyName();
447 if (name
.equals("enabled"))
449 boolean enabled
= ((Boolean
) event
.getNewValue()).booleanValue();
450 JTextField
.this.setEnabled(enabled
);
452 else if (name
.equals(Action
.SHORT_DESCRIPTION
))
454 JTextField
.this.setToolTipText((String
) event
.getNewValue());
464 protected void configurePropertiesFromAction(Action action
)
468 setEnabled(action
.isEnabled());
469 setToolTipText((String
) action
.getValue(Action
.SHORT_DESCRIPTION
));
474 setToolTipText(null);
479 * Returns the column width, which is the width of the character m
480 * for the font in use.
481 * @return the width of the character m for the font in use.
483 protected int getColumnWidth()
485 FontMetrics metrics
= getToolkit().getFontMetrics(getFont());
486 return metrics
.charWidth('m');
490 * Returns the accessible context associated with the <code>JTextField</code>.
492 * @return the accessible context associated with the <code>JTextField</code>
494 public AccessibleContext
getAccessibleContext()
496 if (accessibleContext
== null)
497 accessibleContext
= new AccessibleJTextField();
498 return accessibleContext
;
502 * Returns the bounded range model that describes the horizontal visibility
503 * of the text field in the case when the text does not fit into the
504 * available space. The actual values of this model are managed by the look
505 * and feel implementation.
507 * @return the bounded range model that describes the horizontal visibility
509 public BoundedRangeModel
getHorizontalVisibility()
511 // TODO: The real implementation of this property is still missing.
512 // However, this is not done in JTextField but must instead be handled in
513 // javax.swing.text.FieldView.
514 return horizontalVisibility
;