[Chapter 8] Input Fields

#

| Chapter 8 |

# 8. 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 Chapter 9, 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`.

## 8.1 Text Component

By themselves, the `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

Contents

Both `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 the `TextComponent` as a `String` object.

public void setText (String text)

  The `setText()` method sets the content of the `TextComponent` to `text`. If the `TextComponent` is a `TextArea`, you can embed newline characters (`\n`) in the `text` so that it will appear on multiple lines.

Text selection

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 the `TextComponent` as a `String`. If nothing is selected, `getSelectedText()` returns an empty `String`, not `null`.

public void setSelectionStart (int position)

  The `setSelectionStart()` method changes the beginning of the current selection to `position`. If `position` is after `getSelectionEnd()`, the cursor position moves to `getSelectionEnd()`, and nothing is selected.

public void setSelectionEnd (int position)

  The `setSelectionEnd()` method changes the end of the current selection to `position`. If `position` is before `getSelectionStart()`, the cursor position moves to `position`, and nothing is selected.

public void select (int selectionStart, int selectionEnd)

  The `select()` method selects the text in the `TextComponent` from `selectionStart` to `selectionEnd`. If `selectionStart` is after `selectionEnd`, the cursor position moves to `selectionEnd`. Some platforms allow you to use `select()` to ensure that a particular position is visible on the screen.

public void selectAll ()

  The `selectAll()` method selects all the text in the `TextComponent`. It basically does a `select()` call with a `selectionStart` position of 0 and a `selectionEnd` position of the length of the contents.

Carets

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 the `TextComponent`. You can use this position to paste text from the clipboard with the `java.awt.datatransfer` package described in Chapter 16, Data Transfer.

public void setCaretPosition (int position)

  The `setCaretPosition()` method moves the current text insertion location of the `TextComponent` to `position`. If the `TextComponent` does not have a peer yet, `setCaretPosition()` throws the `IllegalComponentStateException` run-time exception. If `position` < 0, this method throws the run-time exception `IllegalArgumentException`. If `position` 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)`.

Read-only text

By default, a `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 the `TextComponent` to `state`. `true` means the component is editable; `false` means read-only.

public boolean isEditable ()

  The `isEditable()` method tells you if the `TextComponent` 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 95 darkens the background. Motif and Windows NT 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 the `TextComponent` and removes it from the screen. Prior to the `TextComponent` peer's destruction, the current state is saved so that a subsequent call to `addNotify()` will put it back. (`TextArea` and `TextField` each have their own `addNotify()` 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 specific `TextComponent`, put in the customizations for your new class first, and call `super.removeNotify()` last.

protected String paramString ()

  When you call the `toString()` method of a `TextField` or `TextArea`, the default `toString()` method of `Component` is called. This in turn calls `paramString()`, which builds up the string to display. The `TextComponent` level potentially adds four items. The first is the current contents of the `TextComponent` (`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()` and `getSelectionEnd()`).

### 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 registers `listener` as an object interested in receiving notifications when a `TextEvent` passes through the `EventQueue` with this `TextComponent` as its target. The `listener.textValueChanged()` method is called when these events occur. Multiple listeners can be registered.

  The following applet, `text13`, demonstrates how to use a `TextListener` to handle the events that occur when a `TextField` is changed. Whenever the user types into the `TextField`, a `TextEvent` is delivered to the `textValueChanged()` method, which prints a message on the Java console. The applet includes a button that, when pressed, modifies the text field `tf` by calling `setText()`. These changes also generate a `TextEvent`.

    // 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 removes `listener` as an interested listener. If `listener` is not registered, nothing happens.

protected void processEvent(AWTEvent e)

  The `processEvent()` method receives all `AWTEvent`s with this `TextComponent` as its target. `processEvent()` then passes the events along to any listeners for processing. When you subclass `TextComponent`, overriding `processEvent()` allows you to process all events yourself, before sending them to any listeners. In a way, overriding `processEvent()` is like overriding `handleEvent()` using the 1.0 event model.

  If you override `processEvent()`, remember to call `super.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 call `enableEvents()` (inherited from `Component`) to ensure that events are delivered even in the absence of registered listeners.

protected void processTextEvent(TextEvent e)

  The `processTextEvent()` method receives all `TextEvent`s with this `TextComponent` as its target. `processTextEvent()` then passes them along to any listeners for processing. When you subclass `TextField` or `TextArea`, overriding the `processTextEvent()` method allows you to process all text events yourself, before sending them to any listeners. There is no equivalent to `processTextEvent()` within the 1.0 event model.

  If you override `processTextEvent()`, remember to call the method `super.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 call `enableEvents()` (inherited from `Component`) to ensure that events are delivered even in the absence of registered listeners.

Other Layouts Available on the Net |  | TextField