# 7

## JCTextComponent, JCTextArea and JCTextField

Introduction · Sample Program Code · Display Properties

Text Display · User Interaction · Selection Properties

Highlight Properties · TopCharacter and TopRow Properties · Events

Property Listing · Example Programs

## Introduction

Text areas and text fields are standard Graphical User Interface (GUI) components that are common to virtually all windowing systems. Text areas are capable of displaying multiline text areas, while text fields can display a single line of text. They are typically used within programs that require textual information from a user.

Text areas and text fields are included in the Java Development Kit (JDK), but their JClass BWT equivalents offer more control and flexibility than their AWT counterparts. `JCTextArea` and `JCTextField` both offer the programmer direct control over the following elements:

- cursor placement
- alignment
- more methods to access
- better event handling than their AWT equivalents.

For the end user, `JCTextArea` and `JCTextField` both offer the following features:

- Windows 95 look and functionality
- the ability to enter text that is displayed in overstrike mode
- the ability to use MS Windows copy, cut and paste commands.

`JCTextComponent` is an abstract class which is the superclass for both `JCTextArea` and `JCTextField`, and functions in a similar manner to AWT's `TextComponent`.

#### Behavior

`JCTextArea` and `JCTextField` behave in the following way:

- an "I" cursor appears in the text area/field that has focus; if text already appears in the text area/field, the cursor appears at the end of the line of text
- text can be highlighted in a text area/field with the cursor; if a key is pressed when there is highlighted text in the field, the highlighted text disappears and is replaced by the new input
- text added to a text area/field is retained when a particular text area/field loses focus.

#### Keyboard Traversal

The LEFT and RIGHT cursor key move the "I" cursor within any text contained within a text area/field. Pressing the TAB key cycles through multiple text fields contained within an application.

When the scrollbar of a `JCTextArea` has focus, hitting the UP or DOWN cursor keys (for a vertical scrollbar) or the RIGHT or LEFT cursor keys (for a horizontal scrollbar) scrolls the scrollbar in the direction of the cursor key. It also switches focus to the arrow button in the direction of the cursor. Pressing either the ENTER key or the SPACE BAR activates the arrow button (i.e. it is depressed), and it moves the scrollbar in the direction of the arrow button. Clicking PAGE-UP or PAGE-DOWN will scroll up or down by a page respectively. Clicking HOME or END will scroll to the beginning or end of the scrollable area respectively.

## Sample Program Code

The following code fragment shows how both `JCTextArea` and `JCTextField` can be incorporated into a program:

    package jclass.bwt.examples;
    import jclass.bwt.BWTEnum;
    import jclass.bwt.BWTUtil;
    import jclass.bwt.JCAlignerLayout;
    import jclass.bwt.JCLabel;
    import jclass.bwt.JCTextArea;
    import jclass.bwt.JCTextComponent;
    import jclass.bwt.JCTextCursorEvent;
    import jclass.bwt.JCTextCursorListener;
    import jclass.bwt.JCTextField;
    import jclass.bwt.JCTextEvent;
    import jclass.bwt.JCTextListener;
    import jclass.contrib.ContribFrame;
    import java.awt.*;

    /**
     * This example demonstrates the use of a JCTextField and JCTextArea.
     */
    public class text extends java.applet.Applet
    implements JCTextListener, JCTextCursorListener {

    public void textCursorMoveBegin(JCTextCursorEvent ev) {
    	JCTextComponent field = (JCTextComponent) ev.getSource();
    	if (field.getName().equals("phone")) {
    		int new_pos = ev.getNewPosition(), old_pos = ev.getCurrentPosition();
    		if (new_pos == field.getNumChar())
    			return;
    		char c = field.getText().charAt(new_pos);
    		if (c == '-') {
    			if (new_pos> old_pos)
    				ev.setNewPosition(new_pos+1);
    			else
    				ev.setNewPosition(new_pos-1);
    		}
    	}
    }
    public void textCursorMoveEnd(JCTextCursorEvent ev) {}

    public void textValueChangeBegin(JCTextEvent ev) {
    	JCTextComponent field = (JCTextComponent) ev.getSource();
    	if (field.getName().equals("phone")) {
    		boolean allow = true;
    		int text_len = ev.getText().length();

    		if (text_len> 1)
    			allow = false;

    		else if (field.getText().charAt(ev.getStartPosition()) == '-')
    			ev.setText("-");

    		else if (text_len == 1) {
    			char c = ev.getText().charAt(0);
    			if (c != ' ' && !Character.isDigit(c))
    				allow = false;
    		}

    		ev.setAllowChange(allow);
    		if (!allow)
    			field.beep();
    	}
    }

    public void textValueChangeEnd(JCTextEvent ev) {}

    final static String PHONE = "905-555-1212";

    public void init() {
    	JCTextField f1, f2, f3;
    	setBackground(Color.lightGray);
    	setLayout(new JCAlignerLayout(2, 10, 10));

    	add(new JCLabel("Name:"));
    	add(f1 = new JCTextField(System.getProperty("user.name")));
    	f1.setStringCase(BWTEnum.CASE_UPPER);

    	add(new JCLabel("Password:"));
    	add(f2 = new JCTextField("WHO KNOWS?"));
    	f2.setEchoChar('*');

    	add(new JCLabel("Java Vendor:"));
    	add(new JCTextField(System.getProperty("java.vendor")));

    	add(new JCLabel("Phone:"));
    	add(f3 = new JCTextField(PHONE, null, "phone"));
    	f3.setOverstrike(true);
    	f3.setMaximumLength(PHONE.length());
    	f3.addTextListener(this);
    	f3.addTextCursorListener(this);

    	add(new JCLabel("Comments:"));
    	JCTextArea area = new JCTextArea();
    	area.setScrollbarDisplay(BWTEnum.DISPLAY_VERTICAL_ONLY);
    	add(area);
    }

    public static void main(String args[]) {
    	ContribFrame frame = new ContribFrame("Text");
    	text t = new text();

    	t.init();
    	frame.add(t);
    	frame.pack();
    	frame.show();
    }
    }

This code produces the following results:

This sample code is incorporated into the example file `text.class` provided with JClass BWT. For information on how to run these programs, see the " Example Programs " section at the end of this chapter.

## Display Properties

The `Columns` property sets the number of columns, effectively setting the width of a `JCTextField` /`JCTextArea` . Similarly, the `Rows` property sets the number of rows for a `JCTextArea` .

The `PreferredSize` property returns the preferred size of this container. If the application has set the preferred size, it is returned. Otherwise the subclass' `preferredWidth` and/or `preferredHeight` method is called.

The `MaximumLength` property is used to set the maximum number of characters that can be entered into a `JCTextField` by a user (default: MAXINT). If a user attempts to enter more characters in the field, the values are ignored and a bell is sounded. This value is ignored for values set programmatically.

### Scrollbar Display

The display of scrollbars within `JCTextArea` can be set with `ScrollbarDisplay` , which can take one of five values: `DISPLAY_ALWAYS` (scrollbars are always displayed), `DISPLAY_AS_NEEDED` (scrollbars are displayed as necessary), `DISPLAY_VERTICAL_ONLY` (vertical scrollbars only are always displayed), `DISPLAY_HORIZONTAL_ONLY` (horizontal scrollbars only are always displayed), `DISPLAY_NONE` (never display scrollbars). `DISPLAY_AS_NEEDED` is the default setting for `ScrollbarDisplay` .

## Text Display

There are a number of properties that handle the display of text within `JCTextFields` and `JCTextAreas` . It is possible to set the following features within these components:

- the default text (if any) that appears
- the alignment of text
- the color and font of regular text.

It is also possible to set the display values for the selected text. This is discussed in the next section.

### Setting the Default Text

Text can be set in a `JCTextField` /`JCTextArea` by using the `Text` property. Text takes a string of alphanumeric characters which are displayed within the specified `JCTextField` /`JCTextArea` .

### Text Alignment

The `Alignment` property sets the position of the any text within a `JCTextField` /`JCTextArea` . `Alignment` has three values: `LEFT` (default), `CENTER` , or `RIGHT` .

### Text Case

In `JCTextField` it is possible to set the case of the text that is entered by a user or set programmatically by using the `StringCase` property. It takes one of three values: `CASE_AS_IS` (no conversion is made), `CASE_LOWER` (converts all text to lower case) and `CASE_UPPER` (converts all text to upper case). The default value for `StringCase` is `CASE_AS_IS` .

### Text Color and Font

The `Background` and `Foreground` properties can be used to set the color of the background and text/foreground elements of a `JCTextField` /`JCTextArea` . `Foreground` sets the color of any alphanumeric characters contained within the text field.

The display of fonts within a `JCTextField` /`JCTextArea` is controlled by the `Fonts` property. For a listing of available fonts, see Appendix A: Colors and Fonts.

## User Interaction

Most text fields and text areas are designed to accept user input. `JCTextArea` and `JCTextField` have a number of properties that enable the programmer more direct control over the type of textual information users can enter into a program containing JClass BWT components.

The `Editable` property determines whether this component is editable, and the `Traversable` property sets whether the component can accept focus (default: `true` ).

The `CursorPosition` property sets the position of the cursor within a `JCTextField` /`JCTextArea` . The `CaretPosition` property also sets the position of the cursor within a `JCTextField` /`JCTextArea` . It is included for JDK 1.1 compatibility. Both `CursorPosition` and `CaretPosition` work in conjunction with the `ShowCursorPosition` property, which, if set to `true` (default), displays the cursor position with a vertical I-beam.

The `Multiline` property enables a user to break text into multiple lines within a `JCTextArea` . The default value for `Multiline` is `true` .

The `Overstrike` property inserts characters typed by the user into the current text. The default value of `Overstrike` is false.

The `EchoChar` property of `JCTextField` sets the echo character for a text field. Echo characters are useful in cases where user input should not be displayed (or "echoed") to the screen, as in the case of a password prompt. It takes the parameter `c` , which sets the echo character, or `0` if no echo character is to be set.

## Selection Properties

There are several properties that control the display of selected text. `SelectedBackground` property sets the background color of selected text (default: blue), while `SelectedForeground` sets the foreground color of selected text (default: background color).

The `SelectionStart` property is used to get the beginning position, and the `SelectionEnd` property sets the selected text's end position.

The `SelectionList` property sets a list of values used for multi-click. As the mouse is clicked in rapid succession, each click selects the next type in the list. Valid values are: `SELECT_POSITION` (selects the current pointer position), `SELECT_WORD` (selects the current word), `SELECT_LINE` (selects the current line) and `SELECT_ALL` (selects all the text).

## Highlight Properties

In `JCTextField` , there are properties available to set the color and thickness of the highlight, which denotes that a particular `JCTextField` has focus.

The `HighlightColor` property sets the color of the rectangle drawn when the component has focus (default: black), and the `HighlightThickness` property sets the thickness of the rectangle drawn when the component has focus (default: 2).

## TopCharacter and TopRow Properties

the `TopCharacter` property sets the position of the leftmost character on the first line currently displayed. This position is the number of characters from the beginning of the text buffer. The first character position is 0.

Similarly, the `TopRow` property sets the top-most visible row.

## Events

A class can be notified before and after a `JCTextField` 's or `JCTextArea` 's value has changed by implementing the `JCTextListener` interface and registering itself with the field via `addTextListener` , as the following code demonstrates:

    public interface JCTextListener {
            // Invoked before the field's value is changed. The event's values can be modified via its setXXX methods.
            public void textValueChangeBegin(JCTextEvent e);
            // Invoked after the field's value is changed. Any changes made to the event are ignored.
            public void textValueChangeEnd(JCTextEvent e);
    }
    public class JCTextEvent {
            // Returns the component where the event originated.
            public Object getSource()
            // Returns the event type: TEXT_VALUE_CHANGED.
            public int getId()
            // Gets the starting position of the text to modify.
            public int getStartPosition()
            // Sets the starting position of the text to modify.
            public void setStartPosition(int v)
            // Gets the ending position of the text to modify.
            public int getEndPosition()
            // Sets the ending position of the text to modify.
            public void setEndPosition(int v)
            // Gets the string to be inserted.
            public String getText()
            // Sets the string to be inserted.
            public void setText(String v)
            // Returns true if text is being deleted.
            public boolean isDeletion()
            // Determines whether the value change be allowed.
            public boolean getAllowChange()
            // Determines whether the value change be allowed (default: true).
            public void setAllowChange(boolean v)
    }

A class can be notified before and after the `JCTextField` 's or `JCTextArea` 's cursor has moved by implementing the `JCTextCursorListener` interface and registering itself with the field via `addTextCursorListener` :

    public interface JCTextCursorListener {
            // Invoked before the field's cursor is moved. The event's values can be modified via its setXXX methods.
            public void textCursorMoveBegin(JCTextCursorEvent e);
            // Invoked after the field's cursor is moved. Any changes made to the event are ignored.
            public void textCursorMoveEnd(JCTextCursorEvent e);
    }
    public class JCTextCursorEvent {
            // Returns the component where the event originated.
            public Object getSource()
            // Returns the event type.
            public int getId()
            // Gets the current cursor position.
            public int getCurrentPosition()
            // Gets the new cursor position.
            public int getNewPosition()
            // Sets the new cursor position.
            public void setNewPosition(int v)
            // Determines whether the cursor movement should be allowed.
            public boolean getAllowMovement()
            // Determines whether the cursor movement should be allowed (default: true).
            public void setAllowMovement(boolean v)
    }

`JCTextField` has an additional event. A class can be notified when the user presses the ENTER key in a `JCTextField` by implementing the `JCActionListener` interface and registering itself with the field via `addActionListener` :

    public interface JCActionListener {
            public void actionPerformed(JCActionEvent e);
    }
    public class JCActionEvent {
            // Returns the component where the event originated.
            public Object getSource()
            // Returns the event type: ACTION_PERFORMED.
            public int getId()
    }

## Property Listing

The following is a listing of available properties for `JCTextComponent` , `JCTextArea` and `JCTextField` .

###
jclass.bwt.JCTextComponent

#####

Name | Method | Inherited from
--- | --- | ---
`Alignment` | `setAlignment` | `jclass.bwt.JCTextComponent`
`Background` | `setBackground` | `jclass.bwt.JCComponent`
`CaretPosition` | `setCaretPosition` | `jclass.bwt.JCTextComponent`
`Changed` | `setChanged` | `jclass.bwt.JCTextComponent`
`Columns` | `setColumns` | `jclass.bwt.JCTextComponent`
`CursorPosition` | `setCursorPosition` | `jclass.bwt.JCTextComponent`
`DoubleBuffer` | `setDoubleBuffer` | `jclass.bwt.JCComponent`
`Editable` | `setEditable` | `jclass.bwt.JCTextComponent`
`Font` | `setFont` | `jclass.bwt.JCComponent`
`Foreground` | `setForeground` | `jclass.bwt.JCComponent`
`HighlightColor` | `setHighlightColor` | `jclass.bwt.JCComponent`
`HighlightThickness` | `setHighlightThickness` | `jclass.bwt.JCComponent`
`Insets` | `setInsets` | `jclass.bwt.JCComponent`
`MaximumLength` | `setMaximumLength` | `jclass.bwt.JCTextComponent`
`Overstrike` | `setOverstrike` | `jclass.bwt.JCTextComponent`
`PreferredSize` | `setPreferredSize` | `jclass.bwt.JCComponent`
`SelectedBackground` | `setSelectedBackground` | `jclass.bwt.JCTextComponent`
`SelectedForeground` | `setSelectedForeground` | `jclass.bwt.JCTextComponent`
`SelectionEnd` | `setSelectionEnd` | `jclass.bwt.JCTextComponent`
`SelectionList` | `setSelectionList` | `jclass.bwt.JCTextComponent`
`SelectionStart` | `setSelectionStart` | `jclass.bwt.JCTextComponent`
`ShowCursorPosition` | `setShowCursorPosition` | `jclass.bwt.JCTextComponent`
`StringCase` | `setStringCase` | `jclass.bwt.JCTextComponent`
`Text` | `setText` | `jclass.bwt.JCTextComponent`
`Traversable` | setTraversable | `jclass.bwt.JCComponent`
`UserData` | `setUserData` | `jclass.bwt.JCComponent`

###
jclass.bwt.JCTextArea

#####

Name | Method | Inherited from
--- | --- | ---
`Alignment` | `setAlignment` | `jclass.bwt.JCTextArea`
`Background` | `setBackground` | `jclass.bwt.JCContainer`
`CaretPosition` | `setCaretPosition` | `jclass.bwt.JCTextArea`
`Columns` | `setColumns` | `jclass.bwt.JCTextArea`
`CursorPosition` | `setCursorPosition` | `jclass.bwt.JCTextArea`
`Editable` | `setEditable` | `jclass.bwt.JCTextArea`
`Font` | `setFont` | `jclass.bwt.JCContainer`
`Foreground` | `setForeground` | `jclass.bwt.JCContainer`
`Insets` | `setInsets` | `jclass.bwt.JCContainer`
`Multiline` | `setMultiline` | `jclass.bwt.JCTextArea`
`Overstrike` | `setOverstrike` | `jclass.bwt.JCTextArea`
`PreferredSize` | `setPreferredSize` | `jclass.bwt.JCContainer`
`Rows` | `setRows` | `jclass.bwt.JCTextArea`
`ScrollbarDisplay` | `setScrollbarDisplay` | `jclass.bwt.JCScrolledWindow`
`ScrollbarOffset` | `setScrollbarOffset` | `jclass.bwt.JCScrolledWindow`
`SelectedBackground` | `setSelectedBackground` | `jclass.bwt.JCTextArea`
`SelectedForeground` | `setSelectedForeground` | `jclass.bwt.JCTextArea`
`SelectionEnd` | `setSelectionEnd` | `jclass.bwt.JCTextArea`
`SelectionList` | `setSelectionList` | `jclass.bwt.JCTextArea`
`SelectionStart` | `setSelectionStart` | `jclass.bwt.JCTextArea`
`ShowCursorPosition` | `setShowCursorPosition` | `jclass.bwt.JCTextArea`
`Text` | `setText` | `jclass.bwt.JCTextArea`
`TopCharacter` | `setTopCharacter` | `jclass.bwt.JCTextArea`
`TopRow` | `setTopRow` | `jclass.bwt.JCTextArea`
`UserData` | `setUserData` | `jclass.bwt.JCContainer`

###
jclass.bwt.JCTextField

#####

Name | Method | Inherited from
--- | --- | ---
`Alignment` | `setAlignment` | `jclass.bwt.JCTextComponent`
`Background` | `setBackground` | `jclass.bwt.JCComponent`
`CaretPosition` | `setCaretPosition` | `jclass.bwt.JCTextComponent`
`Changed` | `setChanged` | `jclass.bwt.JCTextComponent`
`Columns` | `setColumns` | `jclass.bwt.JCTextComponent`
`CursorPosition` | `setCursorPosition` | `jclass.bwt.JCTextComponent`
`DoubleBuffer` | `setDoubleBuffer` | `jclass.bwt.JCComponent`
`EchoChar` | `setEchoChar` | `jclass.bwt.JCTextField`
`Editable` | `setEditable` | `jclass.bwt.JCTextComponent`
`Font` | `setFont` | `jclass.bwt.JCComponent`
`Foreground` | `setForeground` | `jclass.bwt.JCComponent`
`HighlightColor` | `setHighlightColor` | `jclass.bwt.JCComponent`
`HighlightThickness` | `setHighlightThickness` | `jclass.bwt.JCComponent`
`Insets` | `setInsets` | `jclass.bwt.JCComponent`
`MaximumLength` | `setMaximumLength` | `jclass.bwt.JCTextComponent`
`Overstrike` | `setOverstrike` | `jclass.bwt.JCTextComponent`
`PreferredSize` | `setPreferredSize` | `jclass.bwt.JCComponent`
`SelectedBackground` | `setSelectedBackground` | `jclass.bwt.JCTextComponent`
`SelectedForeground` | `setSelectedForeground` | `jclass.bwt.JCTextComponent`
`SelectionEnd` | `setSelectionEnd` | `jclass.bwt.JCTextComponent`
`SelectionList` | `setSelectionList` | `jclass.bwt.JCTextComponent`
`SelectionStart` | `setSelectionStart` | `jclass.bwt.JCTextComponent`
`ShowCursorPosition` | `setShowCursorPosition` | `jclass.bwt.JCTextComponent`
`StringCase` | `setStringCase` | `jclass.bwt.JCTextComponent`
`Text` | `setText` | `jclass.bwt.JCTextComponent`
`Traversable` | `setTraversable` | `jclass.bwt.JCComponent`
`UserData` | `setUserData` | `jclass.bwt.JCComponent`

## Example Programs

Demonstration programs and example code containing `JCTextArea` and `JCTextField` come with JClass BWT. The examples can be viewed in applet form by launching index.html within the /jclass/bwt/examples directory. textarea.class and textfield.class can also be run as stand-alone Java applications from the command prompt by typing:

    	java jclass.bwt.examples.text