Java Tutorial - lesson eight


Lesson Eight: Making all buttons work.

previous lesson - back to tutorial index - next lesson


Nice. There is one button working so now it is time to make all buttons work. Naturally, we could make a new class like ButtonListener for every button, but it might be nicer to combine things. We can accomplish this by attaching the same instance of ButtonListener to all the buttons. You might already see what will happen: The same method actionPerformed is executed by pressing every button, and we will have to find out where the button-press-action comes from. We can do just this with the method getSource() of the ActionEvent, the parameter that is passed to the method actionPerformed(ActionEvent e).

Instead of copying the entire Calculator class, I will just copy the only method that changes. Change the addButtonListeners() method in your source into:

    private void addButtonListeners() {
        ButtonListener buttonListener= new ButtonListener(this);
        buttonAdd.addActionListener(buttonListener);
        buttonSub.addActionListener(buttonListener);
        buttonMul.addActionListener(buttonListener);
        buttonDiv.addActionListener(buttonListener);
    }

 

And change the ButtonListener class in:

import java.awt.event.*;
//---------------------------------------------
// Class
//---------------------------------------------
public class ButtonListener implements ActionListener {
    private Calculator calculator;
//---------------------------------------------
// Constructor
//---------------------------------------------
    public ButtonListener(Calculator c) {
        this.calculator= c;
    }
//---------------------------------------------
// Methods
//---------------------------------------------
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==calculator.buttonAdd) {
            System.out.println("Button + was pressed...");
        }
        if(e.getSource()==calculator.buttonSub) {
            System.out.println("Button - was pressed...");
        }
        if(e.getSource()==calculator.buttonMul) {
            System.out.println("Button * was pressed...");
        }
        if(e.getSource()==calculator.buttonDiv) {
            System.out.println("Button / was pressed...");
        }
    }
}

 

And as you try to compile this code, you get four error messages that say that the buttons have private access in Calculator. In ButtonListener, the buttons of Calculator are accessed with ´calculator.buttonAdd´, and these variables were private in Calculator. They are not visible outside of the class Calculator. To use them in ButtonListener like we do, we have to make them public. Change the variable declarations in calculator in:

    private TextField numberOne;
    private TextField numberTwo;
    public Button buttonAdd;
    public Button buttonSub;
    public Button buttonMul;
    public Button buttonDiv;
    private Label result;

 

And compile again. This time the code compiles and runs. Every time you press a button, the right part of the code in ButtonListener is executed.

Reviewing the code:

In Calculator, we have attached the same buttonListener to all buttons. Pretty straightforward, I would say. One point, though: We now pass the Calculator (´this´ in Calculator) to the ButtonListener by constructing an instance with ´new ButtonListener(this)´. In ButtonListener the variable ´calculator´ is then defined with ´this.calculator= c´. Every time a button is pressed, the method actionPerformed in ButtonListener is executed, and tests are made to see what component has started (or ´fired´ in Java terminology) the method with ´if(e.getSource()==calculator.buttonAdd)´ (if ´a´ is equal to ´b´).

Variables and methods in classes are accessed by referencing them with a ´.´ in Java. We have seen this happen before, but now it is time to state this explicitly. The ActionEvent that is passed as a parameter in the method actionPerformed is given the name ´e´. To use the method ´getSource()´ in this class to get the appropriate button that started (or fired) the event, we use ´e.getSource()´. It is the same for our own buttons. From ButtonListener, we access the buttons in ´Calculator´ with the variable ´calculator´ (that is defined when constructing the instance of the class ButtonListener) with ´calculator.buttonAdd´.

Remarks:

You could also have declared the buttons protected instead of public, because the classes are in the same directory (or Java package as we will see later). Private, Protected and Public are modifiers that affect the so-called ´visibility´ of variables and methods.

previous lesson - back to tutorial index - next lesson