Chapter 7

Selection

Tuesday, January 13, 2004

 

This chapter explains:

 

Introduction

 

We all make selections in daily life. We wear a coat if it is raining. We buy a CD if we have enough money. Selections are also used a lot in programs. The computer tests a value and according to the result, takes one course of action or another. Whenever the program has a choice of actions and decides to take one action or the other, an if or a switch statement is used to describe the situation.

 

We have seen that a computer program is a series of instructions to a computer. The computer obeys the instructions one after another in sequence. But sometimes we want the computer to carry out a test on some data and then take one of a choice of actions depending on the result of the test. For example, we might want the computer to test someone’s age and then tell them either that they may vote or that they are too young. This is called selection. It uses a statement (or instruction) called the if statement, the central subject of this chapter.

 

if statements are so important that they are used in every programming language that has ever been invented.

 

The if statement

 

Our first example is a program that simulates the digital lock on a safe. The screen is as shown in Figure 7.1. The safe is locked unless the user enters the correct code into a text field, initially empty. When the button is clicked, the program converts the entered text into a number and compares it with the correct code. If the code is correct, a message is displayed.

 

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

 

public class Safe extends JFrame implements ActionListener {

 

    private JLabel greetingLabel;

    private JTextField codeField;

    private JButton button;

    private JTextField outcomeTextField;

 

    public static void main(String[] args) {

        Safe demo = new Safe();

        demo.setSize(100,150);

        demo.createGUI();

        demo.show();

    }

 

    private void createGUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container window = getContentPane();

        window.setLayout(new FlowLayout());

 

        greetingLabel = new JLabel("enter code");

        window.add(greetingLabel);

 

        codeField = new JTextField(5);

        window.add(codeField);

 

        button = new JButton("unlock");

        window.add(button);

        button.addActionListener(this);

 

        outcomeTextField = new JTextField(5);

        window.add(outcomeTextField);

    }

 

    public void actionPerformed(ActionEvent event) {

        String codeString;

        int code;

 

        codeString = codeField.getText();

        code = Integer.parseInt(codeString);

        if (code == 123) {

outcomeTextField.setText("unlocked");

        }

    }

}

 


 

Figure 7.1 Screen for the safe program.

 

The if statement tests the value of the number entered. If the number equals the value 123, the statement sandwiched between the curly brackets (braces) is carried out. Next any statement after the closing brace is executed. On the other hand, if the number is not equal to 123, the sandwiched statement is ignored and any statement after the closing brace is executed.

 

Notice that the condition being tested is enclosed in brackets and this is a grammatical rule of Java.

 

Notice also that a test for equality uses the == operator (not the = operator, which is used for assignment).

 

One way of visualizing an if statement is as an activity diagram (Figure 7.2). This shows the above if statement in graphical form. To use this diagram, start at the blob at the top and follow the arrows. A decision is shown as a diamond, with the two possible conditions shown in square brackets. Actions are shown in rounded boxes and the end of the sequence is a specially-shaped blob at the bottom of the diagram.

 

Figure 7.2 Activity diagram for an if statement.

 

There are two parts to the if statement:

 

 

All programs consist of a sequence of actions, and the sequence evident here is:

 

1.         A piece of text is input from the text field.

2.         Next a test is done.

3.         If appropriate, a message is displayed to say that the safe is unlocked.

 

Very often we want not just one, but a complete sequence of actions carried out if the result of the test is true, and these are sandwiched between the braces.

 

Notice that a line is indented to reflect the structure of the if statement. Indentation means using spaces to push the text over to the right. Although indentation is not essential, it is highly desirable so that the (human) reader of a program can understand it easily. All good programs (whatever the language) have indentation and all good programmers use it.

 

Self Test Question

Enhance the if statement so that it clears a number with the correct code entered into the text field

Answer

if (code == 123) {

    outcomeTextField.setText("unlocked");

    codeField.setText("");

}

End of STQ

 

if ... else

 

Sometimes we want to specify two sequences of actions – those that are carried out if the condition is true and those that are carried out if the condition is false.

 

The user of the voting checker program enters their age into a text field and the program decides whether they can vote or not. The screen is shown in Figure 7.3. When the user clicks on the button, the program extracts the information that the user has entered into the text field, converts the string into an integer and places the number in the variable called age. Next we want the program to take different actions depending on whether the value is:

or

 

This is achieved using the if statement:

if (age > 17) {

    decisionField.setText("you may vote");

commentaryField.setText("congratulations");

}

else {

    decisionField.setText("you may not vote");

    commentaryField.setText("sorry");

}

 

The results of the test are displayed in a number of text fields. The complete program is as follows:


 

Figure 7.3 The voting checking program screen

 

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

 

public class Voting extends JFrame implements ActionListener {

 

    private JLabel greetingLabel;

    private JTextField ageField;

    private JButton button;

    private JTextField decisionField;

    private JTextField commentaryField;

    private JTextField signOffField;

 

    public static void main(String[] args) {

        Voting demo = new Voting();

        demo.setSize(125,200);

        demo.createGUI();

        demo.show();

    }

 

    private void createGUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container window = getContentPane();

        window.setLayout(new FlowLayout());

 

        greetingLabel = new JLabel("enter your age");

        window.add(greetingLabel);

 

        ageField = new JTextField(5);

        window.add(ageField);

 

        button = new JButton("check");

        window.add(button);

        button.addActionListener(this);

 

        decisionField = new JTextField(10);

        window.add(decisionField);

 

        commentaryField = new JTextField(10);

        window.add(commentaryField);

 

        signOffField = new JTextField(10);

        window.add(signOffField);

    }

 

    public void actionPerformed(ActionEvent event) {

        int age;

 

        age = Integer.parseInt(ageField.getText());

        if (age > 17)

        {

            decisionField.setText("you may vote");

commentaryField.setText("congratulations");

        }

        else

        {

            decisionField.setText("you may not vote");

commentaryField.setText("sorry");

        }

        signOffField.setText("Best Wishes");

    }

}

 

There are three parts to the if statement in this program:

The new element here is the word else, which introduces the second part of the if statement. Notice again how the indentation helps to emphasize the intention of the program.

 

We can visualize an if...else statement as an activity diagram, as shown in Figure 7.4. The diagram shows the condition being tested and the two separate actions.


Figure 7.4 Activity diagram for an if...else statement.

 

Comparison operators

 

The programs above used some of the comparison (sometimes called relational) operators. Here is a complete list:

symbol

means

>

greater than

<

less than

==

equals

!=

not equal to

<=

less than or equal to

>=

greater than or equal to

 

Notice again that Java uses two equals signs (==) to test whether two things are equal.

Choosing the appropriate operator often has to be done with great care. In the program to test whether someone can vote, the appropriate test should probably be:

 

if (age >= 18) {

    decisionField.setText("you can vote");

}

 

Note that it is always possible to write conditions in either of two ways. The following two program fragments achieve exactly the same result, but use different conditions:

if (age >= 18) {

    decisionField.setText("you may vote");

}

else {

    decisionField.setText("sorry");

}

 

achieves the same end as:

 

if (age < 18) {

    decisionField.setText("sorry");

}

else {

    decisionField.setText("you may vote");

}

 

Although these two fragments achieve the same end result, the first is probably better, because it spells out more clearly the condition for eligibility to vote.

SELF-TEST QUESTION

7.1 Do these two pieces of Java achieve the same end or not?

 

if (age > 18) {

    decisionField.setText("you may vote");

}

 

if (age < 18) {

    decisionField.setText("you may not vote");

}

 

Answer           

No, because they treat the particular age of 18 differently.

------------------------------------------------------------------

 

Humans sometimes have difficulty in judging the relative sizes of circles of different colors. The next program uses two sliders, and displays circles with equivalent sizes (Figure 7.5). The program compares the sizes and reports on which one is the larger. Let us first write the program using the following if statement:

if (redValue > blueValue) {

    textField.setText("red is bigger");   

}   

else {

    textField.setText("blue is bigger");   

}

 

The library method fillOval is used to draw a solid circle whose diameter is equal to the value obtained from the corresponding slider. The complete program is:

 

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.event.*;

 

public class Bigger extends JFrame

                    implements ChangeListener {

 

    private JSlider redSlider;

    private JPanel panel;

    private JSlider blueSlider;

    private JTextField textField;

 

    public static void main(String[] args) {

        Bigger demo = new Bigger();

        demo.setSize(300,300);

        demo.createGUI();

        demo.show();

    }

 

    private void createGUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container window = getContentPane();

        window.setLayout(new FlowLayout());

 

        redSlider = new JSlider(JSlider.VERTICAL);

        redSlider.addChangeListener(this);

        window.add(redSlider);

 

        panel = new JPanel();

        panel.setPreferredSize(new Dimension(200, 150));

        panel.setBackground(Color.white);

        window.add(panel);

 

        blueSlider = new JSlider(JSlider.VERTICAL);

        blueSlider.addChangeListener(this);

        window.add(blueSlider);

 

        textField = new JTextField(10);

        window.add(textField);

    }

 

    public void stateChanged(ChangeEvent e) {

        Graphics paper = panel.getGraphics();

 

        int redValue, blueValue;   

        redValue = redSlider.getValue();   

        blueValue = blueSlider.getValue();   

 

        paper.setColor(Color.white);

        paper.fillRect(0, 0, 200, 150);

        paper.setColor(Color.red);  

        paper.fillOval(10, 10, redValue, redValue); 

        paper.setColor(Color.blue); 

        paper.fillOval(100, 10, blueValue, blueValue);   

 

        if (redValue > blueValue) {

            textField.setText("red is bigger");

        }   

        else {

            textField.setText("blue is bigger");   

        }

    }

}

 

 

Figure 7.5 The bigger program.

This program seems to work fine, but again illustrates the importance of care when you use if statements. In this program, what happens when the two values are equal? The answer is that the program finds that blue is bigger – which is clearly not the case. We could enhance the program to spell things out more clearly by changing the if statement to:

if (redValue > blueValue) {

    textField.setText("red is bigger");

}

if (blueValue > redValue) {

    textField.setText("blue is bigger");

}

if (redValue == blueValue) {

    textField.setText("They are equal");

}

 

This next example is a program that keeps track of the largest value achieved, as a number changes. This is a common exercise in programming. Some thermometers have a mechanism for recording the maximum temperature that has been reached. This program simulates such a thermometer using a slider. It displays the value of the maximum value that the slider is set to (see Figure 7.6).

The program uses variable named max, a class level variable that holds the value of the largest temperature achieved so far. max is declared like this:

private int max = 0;

 

An if statement compares the current value of the slider with the value of max, and alters max if necessary:

 

int temp;   

temp = slider.getValue();

if (temp > max) {

    max = temp;

}

 

The complete program is:

 


 

Figure 7.6 Screen for the thermometer.

 

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.event.*;

 

public class Max extends JFrame implements ChangeListener, ActionListener {

 

    private JSlider slider;

    private JTextField textField;

    private JButton button;

 

    private int max = 0;

 

    public static void main(String[] args) {

        Max demo = new Max();

        demo.setSize(200,300);

        demo.createGUI();

        demo.show();

    }

 

    private void createGUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container window = getContentPane();

        window.setLayout(new FlowLayout());

        slider = new JSlider(JSlider.VERTICAL, 0, 100, 0);

        slider.setMajorTickSpacing(10);

        slider.setPaintTicks(true);

        slider.addChangeListener(this);

        window.add(slider);

 

        textField = new JTextField(12);

        window.add(textField);

 

        button = new JButton("reset");

        button.addActionListener(this);

        window.add(button);

    }

 

    public void stateChanged(ChangeEvent e) {

        int temp;   

        temp = slider.getValue();

        if (temp > max) {

            max = temp;

        }

        display();

    }

 

    public void actionPerformed(ActionEvent event) {

        textField.setText("");

        max = 0;

    }

 

    private void display() {

        textField.setText("maximum value is " + max);

    }

}

 

SELF-TEST QUESTION

7.2       Write a program that displays the numerical value of the minimum value that the slider is set to.

 

Answer           

The essential part of this program is:

 

if (temp < min) {

    min = temp;

}

textField.setText("Minimum value is " + min);

 

 

We now consider a program that simulates throwing two dice. The computer decides the die values randomly. We will create a button, with the caption ‘throw’. When it is clicked, the program will obtain two random numbers and use them as the die values (Figure 7.7).


 

Figure 7.7 Gambling.

To get a random number, we use the method nextInt from the library class Random. We met this class back in chapter 6. What we need for our purpose is an integer in the range 1 to 6. So we get numbers in the range 0 to 5 and simply add 1 to them.

 

The program to throw two dice is given below.

 

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.util.*;

 

class Gambling extends JFrame implements ActionListener {

 

    private JButton button;

    private JTextField valuesTextField, resultTextField;

    private Random random;

 

    public static void main(String[] args) {

        Gambling demo = new Gambling();

        demo.setSize(200,150);

        demo.createGUI();

        demo.show();

    }

 

    private void createGUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container window = getContentPane();

        window.setLayout(new FlowLayout());

 

        button = new JButton("throw");

        window.add(button);

        button.addActionListener(this);

 

        valuesTextField = new JTextField(14);

        window.add(valuesTextField);

 

        resultTextField = new JTextField(12);

        window.add(resultTextField);

 

        random = new Random();

    }

 

    public void actionPerformed(ActionEvent event) {

        int die1, die2;

 

        die1 = random.nextInt(6) + 1;

        die2 = random.nextInt(6) + 1;

 

        valuesTextField.setText("the die values are "

            + Integer.toString(die1) + " and "

            + Integer.toString(die2));

        if (die1 == die2) {

            resultTextField.setText("dice equal - a win");

        }

        else {

            resultTextField.setText("dice not equal - lose");

        }

    }

}

 

Multiple events

 

The if statement can fulfill an important role in handling multiple events. For example, a simple program has two buttons, with the captions 1 and 2, Figure 8.  When a button is clicked, the program displays the number of the button. Whichever button click event occurs, the same method, actionPerformed, is called. So how do we distinguish between them? An if statement is used to detect which button was clicked. Then the appropriate action can be taken.


 

Figure 8 Multiple buttons

When a button event occurs, the operating system calls method actionPerformed. This, central, part of the program is:

 

    public void actionPerformed(ActionEvent event) {

        Object source = event.getSource();

        if (source == button1) {

            textField.setText("button 1");

        }

        else {

            textField.setText("button 2");

        }

    }

 

The parameter passed to actionPerformed, named event in the program, provides information about the nature of the event. Using method getSource on event returns the object that was responsible for the event. We place this in a variable named source, an object of the class Object. Then we use an if statement to compare this object with the possible candidates. Thus we are using the == operator to compare objects, not numbers or strings. (Note that it is not the = operator.)

The full text of the program is:

 

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

 

class Buttons extends JFrame implements ActionListener {

 

    private JButton button1, button2;

    private JTextField textField;

 

    public static void main(String[] args) {

        Buttons demo = new Buttons();

        demo.setSize(100,100);

        demo.createGUI();

        demo.show();

    }

 

    private void createGUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container window = getContentPane();

        window.setLayout(new FlowLayout());

 

        button1 = new JButton("1");

        window.add(button1);

        button1.addActionListener(this);

 

        button2 = new JButton("2");

        window.add(button2);

        button2.addActionListener(this);

 

        textField = new JTextField(6);

        window.add(textField);

    }

 

    public void actionPerformed(ActionEvent event) {

        Object source = event.getSource();

        if (source == button1) {

            textField.setText("button 1");

        }

        else {

            textField.setText("button 2");

        }

    }

}

 

Self Test Question

Suppose there are three buttons, with captions 1, 2 and 3. Write the code to display the number of the button that is clicked.

Answer

    public void actionPerformed(ActionEvent event) {

        Object source;

        source = event.getSource();

        if (source == button1) {

            textField.setText("button 1");

        }

        if (source == button2) {

            textField.setText("button 2");

        }

        if (source == button3) {

            textField.setText("button 3");

        }

    }

 

And, Or, Not

 

Often in programming we need to test two things at once. Suppose, for example, we want to test whether someone should pay a junior rate for a ticket:

if (age >= 6 && age < 16) {

    textField.setText("junior rate");

}

 

The word && is one of the Java logical operators and simply means ‘and’ as we would use it in English.

 

Additional brackets can be used to improve the readability of these more complex conditions. For example we can rewrite the above statement as:

if ((age >= 6) && (age < 16)) {

    textField.setText("junior rate");

}

 

Although the inner brackets are not essential, they serve to distinguish the two conditions being tested.

It might be very tempting to write:

 

if (age >= 6 && < 16) // error!

 

but this is incorrect.  Instead, the conditions have to be spelled out in full as follows:

 

if (age >= 6 && age < 16) // OK

We would use the || operator, meaning or, in an if statement like this:

 

if (age < 6 || age >= 60) {

    textField.setText("reduced rate");

}

 

in which the reduced rate is applicable for people who are younger than 6 or 60 plus.

 

The ! operator means "not" and gets a lot of use in programming, even though in English the use of a negative can suffer from lack of clarity. Here is an example of the use of not:

if (! (age > 16)) {

    textField.setText("too young");

}

 

This means: test to see if the age is greater than 16. If this result is true, the ! makes it false. If it is false, the ! makes it true. Then, if the outcome is true, display the message. This can, of course, be written more simply without the ! operator.

SELF-TEST QUESTION

7.3       Rewrite the above if statement without using the ! operator.

 

Answer           

if (age <= 16) {

    textField.setText("too young");

}

 

 

The next program illustrates complex tests. Two dice are thrown in a betting game and the program has to decide what the result is. The program uses two sliders, each with a range of 1 to 6 to specify the values of each of the two dice (Figure 7.9). The outcome is displayed in two text fields. Initially, we make the rule that only a total score of six wins anything.


 

Figure 7.9 The dice program

 

The program code is given below. Whenever either of the two sliders is moved, the program displays the total value and uses an if statement to see whether there is a win.

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.event.*;

 

public class Dice extends JFrame implements ChangeListener {

 

    private JSlider slider1, slider2;

    private JTextField totalTextField, commentTextField;

 

    public static void main(String[] args) {

        Dice demo = new Dice();

        demo.setSize(200,150);

        demo.createGUI();

        demo.show();

    }

 

    private void createGUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container window = getContentPane();

        window.setLayout(new FlowLayout());

 

        slider1 = new JSlider(1, 6, 3);

        slider1.addChangeListener(this);

        window.add(slider1);

 

        slider2 = new JSlider(1, 6, 3);

        slider2.addChangeListener(this);

        window.add(slider2);

 

        totalTextField = new JTextField(10);

        window.add(totalTextField);

 

        commentTextField= new JTextField(10);

        window.add(commentTextField);

    }

 

    public void stateChanged(ChangeEvent e) {

        int die1, die2, total;

 

        die1 = slider1.getValue();

        die2 = slider2.getValue();

        total = die1 + die2;

        totalTextField.setText("total is " + total);

        if (total == 6) {

            commentTextField.setText("you have won");

        }

        else {

            commentTextField.setText("you have lost");

        }

    }

}

 

Now we will alter the rules and see how to rewrite the program. Suppose that any pair of identical values wins, i.e. two ones, two twos etc. Then the if statement is:

if (die1 == die2) {

    commentTextField.setText("you have won");

}

 

Now let’s suppose that you only win if you get a total of either 2 or 7:

 

if ((total == 2) || (total == 7)) {

    commentTextField.setText("you have won");

}

 

Notice again that we have enclosed each of the conditions within brackets. These brackets aren’t strictly necessary in Java, but they help a lot to clarify the meaning of the condition to be tested.

The Java and, or and not operators are summarized in the following table:

 

symbol

meaning

&&

and

||

or

!

not

SELF-TEST QUESTIONS

7.4       Alter the dice program so that a win is a total value of 2, 5 or 7.

Answer

if ((total == 2) || (total == 5) || (total == 7)) {

    textField.setText("you have won");

}

 

7.5       Write if statements to test whether someone is eligible for full-time employment. The rule is that you must be 16 or above and younger than 65.

Answer           

if ((age >= 16) && (age < 65)) {

    JOptionPane.showMessageDialog(null, "you are eligible");

}

 

Nested ifs

 

Look at the following program fragment:

 

if (age < 6) {

    textField.setText("child rate");

}

else {

    if (age < 16) {

    textField.setText("junior rate");

    }

    else {

        textField.setText("adult rate");

    }

}

 

You will see that the second if statement is completely contained within the first. (The indentation helps to make this clear.) This is called nesting. Nesting is not the same as indentation – it is just that the indentation makes the nesting very apparent.

The effect of this piece of program is:

 

            

It is common to see nesting in programs, but a program like this has a complexity which makes it slightly difficult to understand. This section of program can be re-written, in a style of nested ifs known as the else-if, as follows:

 

if (age < 6) {

    textField.setText("child rate");

}

else if (age < 16) {

    textField.setText("junior rate");

}

else {

    textField.setText("adult rate");

}

 

This version is exactly the same as the above version above except that the indentation is different and some of the pairs of curly brackets have been eliminated. This is because the rule is that when there is only a single statement to be executed, you can dispense with the curly brackets. This is the only occasion when we recommend omitting the curly brackets.

 

Here is a third version of this piece of program. Sometimes it is possible to write a program more simply using the logical operators.  Here, for example, the same result as above is achieved without nesting:

if (age < 6) {

    textField.setText("child rate");

}

if ((age >= 6) && (age < 16)) {

    textField.setText("junior rate");

}

if (age >= 16) {

    textField.setText("adult rate");

}

 

We now have three pieces of program that achieve the same end result, two with nesting and one without. Some people argue that it is hard to understand nesting, such a program is prone to errors and that therefore nesting should be avoided. Nesting can often be avoided using the logical operators.

SELF-TEST QUESTIONS

7.6       Write a program to input a salary from a slider and determine how much tax someone should pay according to the following rules:

              People pay no tax if they earn up to $10,000. They pay tax at the rate of 20% on the amount they earn over $10,000 but up to $50,000. They pay tax at 90%on any money they earn over $50,000. The slider should have a range from 0 to 100,000.

Answer

int salary, tax;

 

salary = slider.getValue();

 

if ((salary > 10000) && (salary <= 50000)) {

    tax = (salary - 10000)/5;

}

if (salary > 50000) {

    tax = 8000 + ((salary - 50000) * 9 / 10);

}

if (salary <= 10000) {

    tax = 0;

}

 

7.7       Write a program that creates three sliders and displays the largest of the three values.

Answer           

public void stateChanged(ChangeEvent e) {

    int a, b, c;

    int largest;

 

    a = slider1.getValue();

    b = slider2.getValue();

    c = slider3.getValue();

 

    if ((a >= b) && (a >= c)) {

        largest = a;

    }

    else if ((b >= a) && (b >= c)) {

        largest = b;

    }

    else {       

        largest = c;

    }

    JOptionPane.showMessageDialog(null,

           "largest value is " + largest);

}

 

7.8       The Young and Beautiful vacation company restricts its clients to ages between 18 and 30. (Below 18 you have no money; after 30 you have too many wrinkles.) Write a program to test whether you are eligible to go on vacation with this company. The age is entered into a text field. The outcome is displayed in a second text field when a button is clicked.

Answer           

int age;

 

age = Integer.parseInt(ageTextField.getText());

if ((age >= 18) && (age <= 30)) {

    outcomeTextField.setText("you are eligible");

}

 

switch

 

The switch statement is another way of doing a lot of if statements. You can always accomplish everything you need with the aid of if statements but switch can be neater in appropriate circumstances. For example, suppose we need a piece of program to display the day of the week as a string. Suppose that the program represents the day of the week as an int variable called dayNumber, which has one of the values 1 to 7, representing the days Monday to Sunday. We want to convert the integer version of the day into a string version called dayName. We could write the following series of if statements:

if (dayNumber == 1) {

    dayName = "Monday";

}

if (dayNumber == 2); {

    dayName = "Tuesday";

}

if (dayNumber == 3); {

    dayName = "Wednesday";

}

if (dayNumber == 4); {

    dayName = "Thursday";

}

if (dayNumber == 5) {

    dayName = "Friday";

}

if (dayNumber == 6) {

    dayName = "Saturday";

}

if (dayNumber == 7) {

    dayName = "Sunday";

}

 

Now although this piece of coding is clear and well-structured, there is an alternative that has the same effect using the switch statement:

 

switch (dayNumber) {

 

    case 1:

        dayName = "Monday";

        break;

 

    case 2:

        dayName = "Tuesday";

        break;

 

    case 3:

        dayName = "Wednesday";

        break;

 

    case 4:

        dayName = "Thursday";

        break;

 

    case 5:

        dayName = "Friday";

        break;

 

    case 6:

        dayName = "Saturday";

        break;

 

    case 7:

        dayName = "Sunday";

        break;

}

 

The break statement transfers control to the very end of the switch statement, marked with a brace. This now exploits the symmetry of what needs to happen more clearly than the equivalent series of ifs.

A switch statement like this can be visualized as an activity diagram in Figure 7.10.

Figure 7.10 Activity diagram showing part of a switch statement.

 

SELF-TEST QUESTION

7.9       Write a method that converts the integers 1, 2, 3 and 4 into the words diamonds, hearts, clubs and spades respectively.

 

Answer

private String convert(int s) {

    String suit;

 

    switch (s) {

        case 1:                             

            suit = "diamonds";

            break;

        case 2:

            suit = "hearts";

            break;

        case 3: 

            suit = "clubs";

            break;

        case 4: 

            suit = "spades";

            break;

        default:

            suit = "error";

            break;

    }

    return suit;

}

 

 

Several statements can follow one of the options in a switch statement. For example, one of the options could be:

 

case 6:

    JOptionPane.showMessageDialog(null, "hurray");

    dayName = "Saturday";

    break;

 

Another feature of the switch statement is grouping several options together, like this:

switch (dayNumber) {

 

    case 1:

    case 2:

    case 3:

    case 4:

    case 5:

        dayName = "weekday";

        break;

 

    case 6:

    case 7:

        dayName = "weekend";

        break;

}

 

Another, sometimes useful, part of the switch statement is the default option. Suppose in the above example that the value of the integer denoting the day of the week is input from a text field. Then there is the distinct possibility that the user will erroneously enter a number that is not in the range 1 to 7. Any decent program needs to take account of this, in order to prevent something odd happening or the program crashing. The switch statement is very good at dealing with this situation, because we can supply a ‘catch-all’ or default option that will be used if none of the others are valid:

switch (dayNumber) {

 

    case 1:

        dayName = "Monday";

        break;

 

    case 2:

        dayName = "Tuesday";

        break;

 

    case 3:

        dayName = "Wednesday";

        break;

 

    case 4:

        dayName = "Thursday";

        break;

 

    case 5:

        dayName = "Friday";

        break;

 

    case 6:

        dayName = "Saturday";

        break;

 

    case 7:

        dayName = "Sunday";

        break;

 

    default:

        dayName = "illegal day";

        break;

}

 

If a default option is omitted from a switch statement and if none of the cases provided corresponds to the actual value of the variable, then all the options are ignored.

 

Boolean variables

 

All of the types of variable that we have met so far are designed to hold numbers, strings or objects. Now we meet a new kind of variable called a boolean, which can only hold either the value true or the value false. The words boolean, true and false are reserved keywords in Java and cannot be used for any other purpose. This type of variable is named after the 19th century British mathematician George Boole who made a large contribution towards the development of mathematical logic, in which the ideas of true and false play a central role.

This next program displays a shop sign (Figure 7.11). The sign says open or closed. A boolean variable, named open is used to record whether the shop is open (true) or closed (false). Two buttons enable the shopkeeper to switch the sign to open or to closed. Another two buttons switch the sign on and off. The program displays large font letters by using the setFont method.

 

The boolean open is a class level variable, initially false, to denote that the shop is closed:

 

private boolean open = false;

 

When the open button is clicked:

 

open = true;

 

When the closed button is clicked:

 

open = false;

 

When the on button is clicked, the value of open is tested with an if statement and the appropriate sign displayed:

 

if (open) {

    textField.setText("Open");

}

else {

    textField.setText("Closed");

}

 


 

Figure 7.11 The shop sign

 

The complete code is:

 

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

 

public class ShopSign extends JFrame implements ActionListener {

 

    private JButton onButton, offButton, openButton, closedButton;

    private JTextField textField;

 

    private boolean on = false, open = false;

 

    public static void main(String[] args) {

        ShopSign demo = new ShopSign();

        demo.setSize(250,200);

        demo.createGUI();

        demo.show();

    }

    private void createGUI() {

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Container window = getContentPane();

        window.setLayout(new FlowLayout());

 

        onButton = new JButton("On");

        window.add(onButton);

        onButton.addActionListener(this);

 

        offButton = new JButton("Off");

        window.add(offButton);

        offButton.addActionListener(this);

 

        textField = new JTextField(4);

        textField.setSize(5, 100);

        textField.setFont(new Font(null, Font.BOLD, 60));

        window.add(textField);

 

        openButton = new JButton("Open");

        window.add(openButton);

        openButton.addActionListener(this);

 

        closedButton = new JButton("Closed");

        window.add(closedButton);

        closedButton.addActionListener(this);

    }

 

    public void actionPerformed(ActionEvent event) {

        Object source = event.getSource();

        if (source == onButton) {

            handleOnButton();

        }

        else if (source == offButton) {

            handleOffButton();

        }

        else if (source == openButton) {

            handleOpenButton();

        }

        else handleClosedButton();

        drawSign();

    }

 

    private void handleOnButton() {

        on = true;

    }

 

    private void handleOffButton() {

        on = false;

    }

 

    private void handleOpenButton() {

        open = true;

    }

 

    private void handleClosedButton() {

        open = false;

    }

 

    private void drawSign() {

        if (open) {

            textField.setText("Open");

        }

        else {

textField.setText("Closed");

        }

        if (!on) {

            textField.setText("");

        }

    }

}

 

In the above program, one of the if statements is as follows, because the variable open is either true or false and can be tested directly:

 

if (open) {

This is the neater way of testing the value of a boolean variable. It can be re-written less concisely as:

 

if (open = true) {

 

To summarize, boolean variables are used in programming to remember something, perhaps for a short time, perhaps for the whole time that the program is running.

 

Self Test Question

The shop owner needs an additional sign that says "SALE". Can we still use a boolean variable?

Answer

No, because now there are three possible values, not two.

End

 

Methods can use boolean values as parameters and as return values. For example, here is a method that checks whether three numbers are in numerical order:

 

private boolean inOrder(int a, int b, int c) {

    if ((a <= b) && (b <= c)) {

        return true;

    }

    else {

        return false;

    }

}

 

Comparing strings

 

Thus far, we have looked at programs that use the comparison operators (such as >) to compare numbers. However, many programs need to compare strings. The comparison operators are not appropriate and instead, we use the equals method.

 

The safe program above required the user to enter a numeric code. Suppose instead that the code is alphabetic. In this case, the program needs to compare the string entered with the correct code (say “Bill”). The appropriate if statement is:

 

String code;

code = codeField.getText();

if (code.equals(“Bill”)) {

outcomeTextField.setText("unlocked");

}

 

The method equals is called. The parameter is the string “Bill”. The method returns true or false. Then the if statement acts accordingly.

 

Programming principles

 

The computer normally obeys instructions one-by-one in a sequence. An if statement instructs the computer to test the value of some data and then take one of a choice of actions depending on the result of the test. This choice is sometimes called selection. The test of the data is called a condition. After an if statement is completed, the computer continues obeying the instructions in sequence.

 

Programming pitfalls

 

Brackets

 

The condition within an if statement must be enclosed in round brackets, for example:

 

if (a > b) etc

 

 

Equals

 

If you want to test for equality, use the == operator (not a single equals sign, =). So this is correct:

 

if (a == b) etc

 

Unfortunately, a program that uses a single = will compile correctly but work incorrectly.

 

Comparing strings

 

If you want to compare two strings, you must use the equals operator, like this:

 

if (string1.equals(string2)) etc

 

Braces

 

Next we look at braces. This statement is entirely correct:

 

    if (code == 123)

outcomeTextField.setText("unlocked");

 

even though the braces that surround the statement are missing. The Java rule is that if there is only a single statement to be done, then the braces are not necessary. However, this can lead to nuisance programming problems, and the overwhelming advice is to insert the braces at all times. There is a exception to this suggestion when you use nested if statements in the else if style, explained above.

 

Compound conditions

 

You might find that you have written an if statement like this:

 

if (a > 18 && < 25)

 

which is wrong. Instead, the && must link two complete conditions, preferably in brackets for clarity, like this:

 

if ((a > 18) && (a < 25))

 

switch

 

The switch statement is very useful, but unfortunately it is not as flexible as it could be. Suppose, for example, we want to write a piece of program to display two numbers, with the larger first, followed by the smaller. Using if statements, we would write:

if (a > b) {

    textField.setText(Integer.toString(a) + " is greater than "

                  + Integer.toString(b));

}

if (b > a) {

    textField.setText(Integer.toString(b) + " is greater than "

                  + Integer.toString(a));

}

if (a == b) {

    textField.setText("they are equal");

}

 

We may be tempted to rewrite this using a switch statement as follows:

 

switch (?) {  // beware! illegal Java

    case a > b:

        textField.setText(Integer.toString(a) + " is greater than"

                                   + Integer.toString(b));

        break;

 

    case b > a:

        textField.setText(Integer.toString(b) + " is greater than"

                                   + Integer.toString(a));

        break;

 

    case a == b:

        textField.setText("they are equal");

        break;

}

 

but this is not allowed because, as indicated by the question mark, switch only works with a single integer variable (or a char variable) as its subject and case cannot use the operators > == < etc.

 

Grammar spot

 

The first type of if statement has the structure:

 

if (condition) {

    statements

}

 

The second type of if statement has the structure:

 

if (condition) {

    statements

}

else {

    statements

}

 

The switch statement has the structure:

 

switch (variable) {

    case value1:

        statements

        break;

    case value2:

        statements

        break;

    default:

        statements

        break;

}

 

The default section is optional.

 

New language elements

 

      if, else

      switch, case, break, default

 

 

 

 

Summary

 

if statements allow the programmer to control the sequence of actions by making the program carry out a test. Following the test, the computer carries out one of a choice of actions. There are two varieties of if statement:

 

 

The if statement can be used to identify the source of a GUI event. The method getSource returns the object that caused the event. This object is compared with each of the objects that could have caused the event, using the == comparison operator.

 

The switch statement provides a convenient way of carrying out a number of tests. However, the switch statement is restricted to tests on integers or on strings.

 

A boolean variable can be assigned the value true or the value false. A boolean variable can be tested with an if statement. A boolean variable is useful in situations when a variable only has two meaningful values.

 

Exercises

 

7.1 Movie theatre (cinema) price Write a program to work out how much a person pays to go to the cinema. The program should input an age from a slider or a text field and then decide on the following basis:

 

 

7.2 The elevator Write a program to simulate a very primitive elevator. The elevator is represented as a filled black square, displayed in a tall thin white panel. Provide two buttons – one to make it move 20 pixels up the panel and one to make it move down. Then enhance the program to make sure that the elevator does not go too high or too low.

 

 

7.3 Sorting Write a program to input numbers from three sliders, or three text fields, and display them in increasing numerical size.

 

7.4 Betting A group of people are betting on the outcome of three throws of the dice. A person bets $1 on predicting the outcome of the three throws. Write a program that uses the random number method to simulate three throws of a die and displays the winnings according to the following rules:

 

7.5 Digital combination safe Write a program to act as the digital combination lock for a safe. Create three buttons, representing the numbers 1, 2 and 3. The user clicks on the buttons, attempting to enter the correct numbers (say 331121). The program remains unhelpfully quiet until the correct buttons are pressed. Then it congratulates the user with a suitable message. A button is provided to restart.

 

Enhance the program so that it has another button which allows the user to change the safe‘s combination, provided that the correct code has just been entered.

 

7.6 Deal a card Write a program with a single button on it which, when clicked, randomly selects a single playing card. First use the random number generator in the library to create a number in the range 1 to 4. Then convert the number to a suit (heart, diamond, club and spade). Next use the random number generator to create a random number in the range 1 to 13. Convert the number to an ace, 2, 3 etc. and finally display the value of the chosen card. (Hint: use switch as appropriate.)

 

7.7 Rock, scissors, paper game In its original form, each of the two players simultaneously chooses one of rock, scissors or paper. Rock beats scissors, paper beats rock and scissors beats paper. If both players choose the same, it is a draw. Write a program to play the game. The player selects one of three buttons, marked rock, scissors or paper. The computer makes its choice randomly using the random number generator. The computer also decides and displays who has won.

 

7.8 The calculator Write a program which simulates a primitive desk calculator (Figure 7.12) that acts on integer numbers. It has one button for each of the 10 digits, 0 to 9. It has a button to add and a button to subtract. It has a clear button, to clear the display (a text field), and an equals (=) button to get the answer.

 


 

Figure 7.12 The calculator.

 

  When the clear button is clicked the display is set to zero and the (hidden) total is set to zero.

  When a digit button is pressed, the digit is added to the right of those already in the display (if any).

  When the + button is pressed, the number in the display is added to the total (and similarly for the – button).

  When the = button is pressed, the value of the total is displayed.

 

7.9 Nim is a game played with matchsticks. It doesn‘t matter how many matches there are. The matches are put into three piles. Again, it doesn‘t matter how many matches there are in each pile. Each player goes in turn. A player can remove any number of matches from any one pile, but only one pile. A player must remove at least one match. The winner is the player who causes the other player to take the last match.

 

Write a program to play the game. Initially the computer deals three piles, with a random number (in the range 1 to 200) of matches in each pile. The three quantities are displayed in text fields. One player is the computer, which chooses a pile and an amount randomly. The other player is the human user, who specifies the pile number with a button and quantity using a text field.

 

There is also a "new game" button.

 

7.10 Turtle graphics Turtle graphics is a way of making programming easy for young children. Imagine a pen fixed to the belly of a turtle. As the turtle crawls around a floor, the pen draws on the floor. The turtle faces north, south, east or west. The turtle can be issued with commands, with one button for each, as follows:

 

 

Initially the turtle is at the top left of the panel and facing east.

 

So, for example, we can draw a rectangle using the sequence:

 

1. pen down

2. go forward 20 pixels

3. turn right 90°

4. go forward 20 pixels

5. turn right 90°

6. go forward 20 pixels

7. turn right 90°

8. go forward 20 pixels

 

The number of pixels, n, to be moved is input via a slider or a text field. The direction of the turtle (north, south, east, west) is displayed in a text field.