GUI Programming in NetBeans

We have now reached the point in the course where you have seen enough of the basic concepts involved in Java programming to understand the basic principles of graphical user interfaces. In this lab exercise you will create some GUI programs.

Getting started

Create a new, empty Java project. Right-click on the source packages folder in the project view and select New/JFrame Form. Name the new class you create Calculator.

The new class you just created is a frame class used to create windows in a GUI application. By default, the new class will open in the GUI design view.

This view allows you to lay out the components of your user interface and set many of their properties without writing code. As you add new elements to your interface, the GUI designer will automatically generate the necessary Java code to create and set up the GUI elements.

The main pane you see here is the design view, which will give you visual representation of your interface as you build it. The upper right-hand pane is the GUI Palette, which contains interface elements you can add to your window. Find the Text Field element in the Palette under Swing Controls. Drag the Text Field into the design pane to add a text field to your window. Resize and position the text field as shown here.

The pane in the lower right-hand corner is the properties pane. You will use this pane to modify various properties of the interface objects in your frame class. The most important property of each element you add to the interface is its variable name. When you add an object to your frame class, the designer will add a new member variable to your frame class to represent this object. By default, the designer generates a generic name for this member variable. You will generally find it convenient to replace this variable name with a name that is more meaningful to you. To change the variable name property of the text field object you just added, click the Code button at the top of the Properties pane, and locate the Variable Name property in the list below. Change the variable name from the automatically generated name of 'jTextField1' to 'display'.

The only other property we will want to change for this text field is its text property, which specifies what text the field will display when the window appears on the screen. Click the Properties button at the top of the Properties pane and scroll down the list of properties to the text property. Set that property to be empty.

Next, drag a button object into the designer from the palette. Position the button as shown here, set its text property to 'Increment' and its variable name property to 'incrementButton'.

Adding a member variable to the frame class

In addition to member variables for the GUI objects in the window, your frame class can also set up and use member variables to store data. We are going to add member variable to store the integer displayed in the text field.

Click the Source button in the design pane to switch back to the source view for your frame class. Add a member variable

private int counter;

to your class. Add the statements

counter = 0;
display.setText(Integer.toString(counter));

to the end of the constructor method for your class.

Switch back to the design view for the next step.

Binding an action to the button

The action elements of an interface are the buttons and menu commands that trigger actions when the user clicks on them. Next we are going to create an action method for the Increment button. This will be a method of the frame class that will get called when the user clicks the Increment button.

Double-click on the Increment button to create an action method for the button. This should create an action method for the button and switch you to the source view where you can edit the code for the action method. If double-clicking on the button does not create the action method, you can also create it from the Properties pane. Click the Event button in that pane, locate the actionPerformed property, and click the button to the right of that property.

Edit the code of the action method to look like this.

private void incrementButtonActionPerformed(java.awt.event.ActionEvent evt) {
  counter++;
  display.setText(Integer.toString(counter));
}

This code is typical for action methods. In most cases, action methods perform some calculation involving the data member variables of the frame and then update the state of one or more elements of the interface to reflect the changed state of the data variables.

Run your application to confirm that the increment button works correctly.

Making a simple calculator

Switch to the design view and delete the Increment button. Switch to the source view and note that the action method bound to that button is gone now. Replace the counter member variable with member variables

private double memory;
private char operation;

and change the code in the constructor method to

initComponents();
memory = 0.0;
operation = ' ';
display.setText("0.0");

Switch back to the design view. Resize the bounds of the frame and add five buttons to the interface to make it look like this.

Name the button variables 'addButton', 'subtractButton', 'multiplyButton', 'divideButton', and 'equalsButton'. Double-click each of the buttons in turn to add action methods for the five buttons.

Edit the code for the five action methods to look like this:

private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
  memory = Double.parseDouble(display.getText());
  operation = '+';
  display.setText("");
}

private void subtractButtonActionPerformed(java.awt.event.ActionEvent evt) {
  memory = Double.parseDouble(display.getText());
  operation = '-';
  display.setText("");
}

private void multiplyButtonActionPerformed(java.awt.event.ActionEvent evt) {
  memory = Double.parseDouble(display.getText());
  operation = '*';
  display.setText("");
}

private void divideButtonActionPerformed(java.awt.event.ActionEvent evt) {
  memory = Double.parseDouble(display.getText());
  operation = '/';
  display.setText("");
}

private void equalsButtonActionPerformed(java.awt.event.ActionEvent evt) {
  double number = Double.parseDouble(display.getText());
  double result;
  if (operation == '+') {
    result = memory + number;
  } else if (operation == '-') {
    result = memory - number;
  } else if (operation == '*') {
    result = memory * number;
  } else if (operation == '/') {
    result = memory / number;
  } else {
    return;
  }
  operation = ' ';
  display.setText(Double.toString(result));
}

Run your program. It should be a fully functional calculator now.

Programming Assignment

Here is the code for a class I showed earlier in lecture. This class implements a simple guessing game where the user has 10 chances to guess a secret number.

public class Game {

  public static final int CORRECT = 1;
  public static final int TOO_LOW = 0;
  public static final int TOO_HIGH = 2;
  public static final int GAME_OVER = -1;

  private boolean gameOver;
  private int secretNumber;
  private int numberOfGuesses;

  public Game() {
    gameOver = false;
    secretNumber = (int) (Math.random() * 100 + 1);
    numberOfGuesses = 0;
  }

  public Game(int range) {
    gameOver = false;
    secretNumber = (int) (Math.random() * range + 1);
    numberOfGuesses = 0;
  }

  public boolean isGameOver() {
    return gameOver;
  }

  public int guess(int n) {
    if (gameOver) {
        return GAME_OVER;
    } else if (n == secretNumber) {
        gameOver = true;
        return CORRECT;
    } else {
        numberOfGuesses++;
        if (numberOfGuesses == 10) {
            gameOver = true;
        }
        if (n < secretNumber) {
            return TOO_LOW;
        } else {
            return TOO_HIGH;
        }
    }
  }
}

Using this code as a guide, create a simple GUI application that allows the user to play the guessing game. Your project will have two source files in it: a file Game.java whose contents you can copy from the code above and a JFrame form that sets up the GUI window that will act as the interface for your application.

Your frame class will contain a member variable

private Game theGame;

that represents the Game object your interface will be communicating with. You will also need to add code to the frame class's constructor that creates the game object:

theGame = new Game();

Your interface should look something like this:

When the player clicks the guess button, the game will put up a dialog telling the player whether their guess is correct, too high, or too low.

The following code shows how to display a simple message dialog from inside a frame class.

JOptionPane.showMessageDialog(this, "Your guess is too low.");

To use the JOptionPane class, you will need to place the import statement

import javax.swing.JOptionPane;

at the top of the source code for your frame class.

Notice also that in the main window of the program the 'Play Again' button is disabled. You can enable or disable a button by calling the button's setEnabled() method with a parameter of true or false. In this program the 'Guess' button should be initially enabled and should stay enabled until the game is over. As soon as the game ends, the 'Guess' button should be disabled and the 'Play Again' button enabled. When the user clicks 'Play Again' the game will reset to a new game with a new secret number, the 'Guess' button will be enabled again, and the 'Play Again' button disabled.