Text fields and labels

We've now seen an example of two key types of Swing components: the JFrame, which is effectively a window in our user interface, and the JButton, which represents a clickable button. Now we'll add two more weapons to our armoury: JTextField, which can be used for requesting text from the user, and JLabel, which simply displays a piece of static text on screen. In this simple example, we allow the user to enter a number then, when they press the Calculate button, we double the number they entered and display the result.

JTextField: allowing the user to enter a string

To implement a simple text box in Swing, we use the JTextField class. When we construct a JTextField, we can specify the approximate width of the text field in characters:

JTextField numberField = new JTextField(15);

Then, whenever we want to get hold of what the user typed into the field, we call getText() on that text field. (Similarly, there's a setText() method if we want to explicitly set the current text to be a particular string. For example, we might initialise the field to a particular value.) In our program, in response to the user clicking on the button, we want to read the current contents of the text field. So our action listener for the button will look something as follows:

public void actionPerformed(ActionEvent e) {
  String numberStr = numberField.getText();
  numberStr = numberStr.trim();
  double number = Double.parseDouble(numberStr);
  number *= 2;
  resultField.setText("n * 2 = " + String.format("%.2f", number));
}

We need the call to Double.parseDouble() because in order to perform a calculation on the number, we need it as a numeric variable type. The call to Double.parseDouble() effectively "converts" from a string to a decimal value. The String.format() method ensures that only so many decimal places are output. For more information on both of these methods, see our summary of Java string methods.

In this case, resultField is just another JTextField. However, we don't want the user to be able to edit this field: it's just for display purposes. So we can call the following:

resultField.setEditable(false);

We don't need to make such a call with the other text field (for user input) because by default, a JTextField is editable.

JLabel

A JLabel displays a simple piece of text generally designed to label another component. We will use one to label the editable text field, so that the user knows what it is he/she is supposed to be entering. A label can simply be initialised with the string to display:

add(new JLabel("Number to double (n):"),
    BorderLayout.WEST);

(In a moment, we'll explain the BorderLayout.WEST parameter.)

Putting the code together

Because we now have a couple of components that we access in different parts of our program, it's convenient to make them into instance variables of our application. We can make our application class extend JFrame and then create an instance of it. This is good design, since logically speaking, our program is a "number doubling tool" represented by a visual component; it makes sense for us to create an instance of that "tool":

public class MyApplication extends JFrame {
  JTextField numberField = new JTextField(15);
  JTextField resultField = new JTextField(20);

  public static void main(String[] args) {
    MyApplication app = new MyApplication();
    app.setVisible(true);
  }

  private MyApplication() {
    super("Number doubler");
    resultField.setEditable(false);
    add(new JLabel("Number to double (n):"), BorderLayout.WEST);
    add(numberField, BorderLayout.CENTER);
    add(resultField, BorderLayout.SOUTH);
    JButton butt = new JButton("Calculate");
    butt.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        String numberStr = numberField.getText();
        numberStr = numberStr.trim();
        double n = Double.parseDouble(numberStr);
        n *= 2;
        resultField.setText("n * 2 = " + String.format("%.2f", n));
      }
    });
    add(butt, BorderLayout.EAST);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    pack();
  }
}

Notice the call to pack() at the end of the constructor. This is a special method that allows us to set a JFrame to its "natural" size, given the components that were added.

North, south, east and west and centre

When we add a component to the frame, we now specify one of various constants, such as BorderLayout.CENTER. We'll come back to these in a moment. Suffice it to say that we image that the window has five "positions": north, south, east, west and centre, and can then specify a component in each of these positions. Often, we need a more sophisticated layout than this, but here, it gets us started. Border Layout is the name of this type of layout (it is the default layout).

On the next pages, we look properly at Swing layouts. You may also want to take a look at our Swing components overview, which shows some common Swing components and the most common methods and listeners used with them.


If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants.

Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.