Input Fields
Contents:
Text Component
TextField
TextArea
Extending TextField
There are two fundamental ways for users to provide input to a program: they can type on a keyboard, or they can select something (a button, a menu item, etc.) using a mouse. When you want a user to provide input to your program, you can display a list of choices to choose from or allow the user to interact with your program by typing with the keyboard. Presenting choices to the user is covered in Pick Me. As far as keyboard input goes, the java.awt
package provides two options. The TextField
class is a single line input field, while the TextArea
class is a multiline one. Both TextField
and TextArea
are subclasses of the class TextComponent
, which contains all the common functionality of the two. TextComponent
is a subclass of Component
, which is a subclass of Object
. So you inherit all of these methods when you work with either TextField
or TextArea
.
Text Component
TextField
and TextArea
classes are fairly robust. However, in order to reduce duplication between the classes, they both inherit a number of methods from the TextComponent
class. The constructor for TextComponent
is package private, so you cannot create an instance of it yourself. Some of the activities shared by TextField
and TextArea
through the TextComponent
methods include setting the text, getting the text, selecting the text, and making it read-only.
TextComponent Methods
ContentsBoth TextField
and TextArea
contain a set of characters whose content determines the current value of the TextComponent
. The following methods are usually called in response to an external event.
- public String getText ()
- The
getText()
method returns the current contents of theTextComponent
as aString
object. - public void setText (String text)
- The
setText()
method sets the content of theTextComponent
totext
. If theTextComponent
is aTextArea
, you can embed newline characters (\n
) in thetext
so that it will appear on multiple lines.
Users can select text in TextComponents
by pressing a mouse button at a starting point and dragging the cursor across the text. The selected text is displayed in reverse video. Only one block of text can be selected at any given time within a single TextComponent
. Once selected, this block could be used to provide the user with some text-related operation such as cut and paste (on a PopupMenu
).
Depending on the platform, you might or might not be able to get selected text when a TextComponent
does not have the input focus. In general, the component with selected text must have input focus in order for you to retrieve any information about the selection. However, in some environments, the text remains selected when the component no longer has the input focus.
- public int getSelectionStart ()
- The
getSelectionStart()
method returns the initial position of any selected text. The position can be considered the number of characters preceding the first selected character. If there is no selected text,getSelectionStart()
returns the current cursor position. If the start of the selection is at beginning of the text, the return value is 0. - public int getSelectionEnd ()
- The
getSelectionEnd()
method returns the ending cursor position of any selected text--that is, the number of characters preceding the end of the selection. If there is no selected text,getSelectionEnd()
returns the current cursor position. - public String getSelectedText ()
- The
getSelectedText()
method returns the currently selected text of theTextComponent
as aString
. If nothing is selected,getSelectedText()
returns an emptyString
, notnull
. - public void setSelectionStart (int position)
- The
setSelectionStart()
method changes the beginning of the current selection toposition
. Ifposition
is aftergetSelectionEnd()
, the cursor position moves togetSelectionEnd()
, and nothing is selected. - public void setSelectionEnd (int position)
- The
setSelectionEnd()
method changes the end of the current selection toposition
. Ifposition
is beforegetSelectionStart()
, the cursor position moves toposition
, and nothing is selected. - public void select (int selectionStart, int selectionEnd)
- The
select()
method selects the text in theTextComponent
fromselectionStart
toselectionEnd
. IfselectionStart
is afterselectionEnd
, the cursor position moves toselectionEnd
. Some platforms allow you to useselect()
to ensure that a particular position is visible on the screen. - public void selectAll ()
- The
selectAll()
method selects all the text in theTextComponent
. It basically does aselect()
call with aselectionStart
position of 0 and aselectionEnd
position of the length of the contents.
Introduced in Java 1.1 is the ability to set and get the current insertion position within the text object.
- public int getCaretPosition ()
- The
getCaretPosition()
method returns the current text insertion position (often called the "cursor") of theTextComponent
. You can use this position to paste text from the clipboard with thejava.awt.datatransfer
package described in Data Transfer. - public void setCaretPosition (int position)
- The
setCaretPosition()
method moves the current text insertion location of theTextComponent
toposition
. If theTextComponent
does not have a peer yet,setCaretPosition()
throws theIllegalComponentStateException
run-time exception. Ifposition
< 0, this method throws the run-time exceptionIllegalArgumentException
. Ifposition
is too big, the text insertion point is positioned at the end.Prior to Java version 1.1, the insertion location was usually set by calling
select(position, position)
.
TextComponent
is editable. If a user types while the component has input focus, its contents will change. A TextComponent
can also be used in an output-only (read-only) mode.
- public void setEditable (boolean state)
- The
setEditable()
method allows you to change the current editable state of theTextComponent
tostate
.true
means the component is editable;false
means read-only. - public boolean isEditable ()
- The
isEditable()
method tells you if theTextComponent
is editable (true
) or read-only (false
).
The following listing is an applet that toggles the editable status for a TextArea
and sets a label to show the current status. As you can see in Figure 8.1, platforms can change the display characteristics of the TextComponent
to reflect whether the component is editable. (Windows darkens the background. Motif and Windows do nothing.)
import java.awt.*; import java.applet.*; public class readonly extends Applet { TextArea area; Label label; public void init () { setLayout (new BorderLayout (10, 10)); add ("South", new Button ("toggleState")); add ("Center", area = new TextArea ("Help Me", 5, 10)); add ("North", label = new Label ("Editable", Label.CENTER)); } public boolean action (Event e, Object o) { if (e.target instanceof Button) { if ("toggleState".equals(o)) { area.setEditable (!area.isEditable ()); label.setText ((area.isEditable () ? "Editable" : "Read-only")); return true; } } return false; } }
Figure 8.1: Editable and read-only TextAreas
Miscellaneous methods
- public synchronized void removeNotifiy ()
- The
removeNotify()
method destroys the peer of theTextComponent
and removes it from the screen. Prior to theTextComponent
peer's destruction, the current state is saved so that a subsequent call toaddNotify()
will put it back. (TextArea
andTextField
each have their ownaddNotify()
methods.) These methods deal with the peer object, which hides the native platform's implementation of the component. If you override this method for a specificTextComponent
, put in the customizations for your new class first, and callsuper.removeNotify()
last. - protected String paramString ()
- When you call the
toString()
method of aTextField
orTextArea
, the defaulttoString()
method ofComponent
is called. This in turn callsparamString()
, which builds up the string to display. TheTextComponent
level potentially adds four items. The first is the current contents of theTextComponent
(getText()
). If the text is editable,paramString()
adds the word editable to the string. The last two items included are the current selection range (getSelectionStart()
andgetSelectionEnd()
).
TextComponent Events
With the 1.1 event model, you can register listeners for text events. A text event occurs when the component's content changes, either because the user typed something or because the program called a method like setText()
. Listeners are registered with the addTextListener()
method. When the content changes, the TextListener.textValueChanges()
method is called through the protected method processTextEvent()
. There is no equivalent to TextEvent
in Java 1.0; you would have to direct keyboard changes and all programmatic changes to a common method yourself.
In addition to TextEvent
listeners, Key, mouse, and focus listeners are registered through the Component
methods addKeyListener()
, addMouseListener()
, addMouseMotionListener()
, and addFocusListener()
, respectively. Listeners and 1.1 event handling
- public synchronized void addTextListener(TextListener listener)
- The
addTextListener()
method registerslistener
as an object interested in receiving notifications when aTextEvent
passes through theEventQueue
with thisTextComponent
as its target. Thelistener.textValueChanged()
method is called when these events occur. Multiple listeners can be registered.The following applet,
text13
, demonstrates how to use aTextListener
to handle the events that occur when aTextField
is changed. Whenever the user types into theTextField
, aTextEvent
is delivered to thetextValueChanged()
method, which prints a message on the Java console. The applet includes a button that, when pressed, modifies the text fieldtf
by callingsetText()
. These changes also generate aTextEvent
.
// Java 1.1 only import java.applet.*; import java.awt.*; import java.awt.event.*; class TextFieldSetter implements ActionListener { TextField tf; TextFieldSetter (TextField tf) { this.tf = tf; } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals ("Set")) { tf.setText ("Hello"); } } } public class text13 extends Applet implements TextListener { TextField tf; int i=0; public void init () { Button b; tf = new TextField ("Help Text", 20); add (tf); tf.addTextListener (this); add (b = new Button ("Set")); b.addActionListener (new TextFieldSetter (tf)); } public void textValueChanged(TextEvent e) { System.out.println (++i + ": " + e); } }
- public void removeTextListener(TextListener listener)
- The
removeTextListener()
method removeslistener
as an interested listener. Iflistener
is not registered, nothing happens. - protected void processEvent(AWTEvent e)
- The
processEvent()
method receives allAWTEvent
s with thisTextComponent
as its target.processEvent()
then passes the events along to any listeners for processing. When you subclassTextComponent
, overridingprocessEvent()
allows you to process all events yourself, before sending them to any listeners. In a way, overridingprocessEvent()
is like overridinghandleEvent()
using the 1.0 event model.If you override
processEvent()
, remember to callsuper.processEvent(e)
last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to callenableEvents()
(inherited fromComponent
) to ensure that events are delivered even in the absence of registered listeners. - protected void processTextEvent(TextEvent e)
- The
processTextEvent()
method receives allTextEvent
s with thisTextComponent
as its target.processTextEvent()
then passes them along to any listeners for processing. When you subclassTextField
orTextArea
, overriding theprocessTextEvent()
method allows you to process all text events yourself, before sending them to any listeners. There is no equivalent toprocessTextEvent()
within the 1.0 event model.If you override
processTextEvent()
, remember to call the methodsuper.processTextEvent(e)
last to ensure that regular event processing can occur. If you want to process your own events, it's a good idea to callenableEvents()
(inherited fromComponent
) to ensure that events are delivered even in the absence of registered listeners.