13.6 Text Input and Output
Although Swing provides many powerful tools for handling text, we will,
as usual, only look at a very small subset. Our attention will be limited to
the JTextField class which allows us to read and write single lines of text.
A JTextField object appears to a user as an area in which text can
(normally) be typed as it would in any single-line text editor in which text
can be entered and edited (by backspacing, inserting, or deleting).
Example 1
To create a JTextField object called inField, we could write
JTextField inField = new JTextField(20);
This would create a field whose appearance would be about wide enough
to hold at least twenty of the widest characters in the current font (if the
field is displayed at its preferred size).
|
|
The size specified in the constructor does not affect the number of
characters that can by typed in the field, only the number that we can see
at one time. If the size of a window is changed, the size of any JTextField
may be changed by the layout manager. You can, in fact, leave all display
size decisions up to the layout manager by using a constructor with no
argument.
JTextField objects behave in many ways like JButton objects. Both
generate event objects from the class ActionEvent — a JButton object
generates its events when it is pressed while a JTextField object generates
its events when the user presses the key while the cursor is in the
text entry area. To register as a listener to JTextField events, we must
do as we did for JButton events: implement the ActionListener interface
by writing an actionPerformed method.
To determine which button was the source of an action event, we used
the getSource method. We can also use that for JTextField objects.
We can initialize the text in a JTextField by using a slightly different constructor.
For example, if we wanted inField to have the text "Input", then we would
constuct inField by writing
JTextField inField = new JTextField("Input", 20);
If a field is only to be used for output, we can prevent a user from
using the field for input by making the field non-editable.
Example 2
To create a field that can only be used to display output, we could write
JTextField outField = new JTextField("result",10);
outField.setEditable(false);
When displayed, outField will have an appearance that is different from
fields that can be edited.
|
|
To work with the contents of a JTextField, we can convert the value
to a string using the getText method. To get rid of extra white space that
the user may have inserted at either the beginning or end of the input, it
is a good idea to use the trim method of the String class.
Example 3
To convert the JTextField object inField to a string, we could write
String inString = inField.getText();
inString = inString.trim();
Taking advantage of Java’s facility for chaining methods, we usually abbreviate this to
String inString = inField.getText().trim();
|
|
If a JTextField object represents a numerical value, we can obtain
that value using methods available in the wrapper classes associated with
each primitive numerical type. We saw wrapper classes earlier when we
used them to enclose primitive types in objects. The classes also have a
number of utility methods for type conversions. The methods that we are
interested in are those that convert strings to the appropriate numerical
value. These are all class methods that have the form parse.
The table shows the headers of these methods and the classes that contain
them.
Example 4
If a JTextField object called inField represents an integer, we could
extract that value by writing
int inValue = Integer.parseInt(inField.getText().trim());
which first converts the field to a string, then trims off any leading or
trailing white space, and finally converts the trimmed string value to an
integer.
|
|
If the argument of a parse... method is not a string of the appropriate
form, then Java throws a NumberFormatException at execution time. If
the programmer does not catch such exceptions, the program will crash.
To display values in a JTextField that is being used for output, we
must make conversions in the opposite direction. As we have seen before,
the String class contains an overloaded class method valueOf that can
be used to convert the value of any primitive type or object to a string.
Values of strings can be converted to JTextField values using the method
setText, as shown in the next example.
Example 5
To display the double value result in the JTextField called outField,
we could write
outField.setText(String.valueOf(result));
As an alternative to using the valueOf method to convert result to a
string, we could simply concatenate result onto an empty string.
outField.setText("" + result);
By default, values are written left-justified in the display area.
|
|
To identify a JButton, we had a label that appeared on the button.
To label a JTextField, we usually use some text in an area adjacent to the
field. In order to do this, we can create a JLabel object that can display
either text, an image, or both. A label does not react to input events. Text
labels are, by default, located at the left side of their display area, centred
vertically.
Example 6
To create a display area showing the text Age in years: and add it to a
panel called inputPane, we could write
inputPane.add(new JLabel("Age in years:"));
The result would be an area like the following.
|
|
The next example gives a simple illustration of both input and output
of text, the use of labels, and a button to control the display of the output.
The example also illustrates the use of the method pack which requests the
layout manager to display components at their preferred sizes rather than
at some size specified by us using setSize.
Example 7
The program shown here allows a user to supply a given name and a family
name into separate JTextField objects. Whenever the user presses a button
to submit the component names, the program displays the combined
name in a third JTextField.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TextFields implements ActionListener
{
JTextField givenName;
JTextField familyName;
JTextField fullName;
JButton submitButton = new JButton("Submit");
public TextFields()
{
JFrame frame = new JFrame("Text Fields");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create fields for I/O
givenName = new JTextField(10);
familyName = new JTextField(10);
fullName = new JTextField(10);
fullName.setEditable(false);
// Add labelled input fields to display
JPanel inFieldPane = new JPanel();
inFieldPane.setLayout(new GridLayout(2,2));
inFieldPane.add(new JLabel("Given Name"));
inFieldPane.add(givenName);
givenName.addActionListener(this);
inFieldPane.add(new JLabel("Family Name"));
inFieldPane.add(familyName);
familyName.addActionListener(this);
frame.add(inFieldPane,BorderLayout.NORTH);
// Add submission button
JPanel submitPane = new JPanel();
submitPane.setLayout(new FlowLayout());
submitPane.add(new JLabel("Press Button to Enter Names"));
submitButton.addActionListener(this);
submitPane.add(submitButton);
frame.add(submitPane,BorderLayout.CENTER);
// Add Output fields
JPanel outFieldPane = new JPanel();
outFieldPane.setLayout(new GridLayout(1,2));
outFieldPane.add(new JLabel("Full Name"));
outFieldPane.add(fullName);
frame.add(outFieldPane,BorderLayout.SOUTH);
// Display the final product
frame.pack();
frame.setVisible(true);
}
public void actionPerformed (ActionEvent e)
{
// Display full name if and only if button was pushed
if (e.getSource() == submitButton)
{
String fullString = familyName.getText().trim() + ", "
+ givenName.getText().trim();
fullName.setText(fullString);
}
}
public static void main(String[] args)
{
new TextFields();
}
}
Here is a typical window produced by the program.
Notice that the non-editable output field is displayed differently from the
editable input fields.
|
|
As we have stated many times, there are far more features in Swing
than we have space to cover. For those interested in exploring further,
there are many resources available. One book that provides a clear and
much more thorough treatment is Learning Java by Patrick Niemeyer and
Jonathan Knudsen, published by O’Reilly.
Sun’s Java web site, located at http://java.sun.com is another source
of assistance. There you will find, among other things, thorough documentation
of all classes in the API. At first you may find this resource to be
quite intimidating as it often tells you far more than you might ever want
to know but those who persist usually find it to be extremely useful.
Exercise 13.6
- What would you have to do to prevent a user from using a JTextField called result for input?
- What changes would be needed in the actionPerformed method of
Example 7 in order to have the full name updated every time either
the given name or the family name was updated and the <enter> key
was pressed?
- Write a program that displays a window showing a labelled text input
field at the bottom of the screen and a large blank area above this.
The label should prompt the user to enter a positive integer. After the
value is entered and the <enter> key is pressed, the program should
draw that number of small solid circular regions in the window. The
circular regions should be located at randomly chosen points in the
window and should be drawn in randomly selected colours.
- Write a program that will produce a window that can be used as
a simple calculator. The window should have two input fields and
one output field plus buttons for each of the operations +, -, *, and
/. The illustration shows the window that would be produced by
calculating 7 × 5.
|
|