The problem with the program design we have now is that one object is carrying too many responsibilities:
Suppose that you have two buttons. If the main object is the listener for both, then the actionPerformed
method must check which button has been pressed. This is
possible, and might be desirable if the buttons perform very similar
tasks, because you can then share code in the method:
button1.addActionListener(this); button2.addActionListener(this); ... public void actionPerformed(ActionEvent e) { // common code if (e.getSource() == button1) ... else if (e.getSource() == button2} ... }
However, if there are a lot of buttons doing completely different things, then the actionPerformed
method ends up doing too many tests and containing too much unrelated
code. Then it makes sense to have a separate object as a listener
for each button. Since each object has different actionPerfomed
code, you need a separate class for each. If you create a
separate class in a separate file to form a listener object, then it is
difficult for the object to access the program's global
variables. It is not impossible, because the separate class can
have a variable which refers back to the main program object, but that
is a lot of trouble to go to if the buttons perform small pieces of
code which naturally belong in the program class.
There is a compromise, which is to use inner classes. An inner class is a class which is defined inside another one. An object of that inner class is automatically given a reference back to the parent object, and so the code in the inner class can refer to data in the outer class. Here is an example with two buttons:
...
class BankAccount extends JFrame
{
...
depositButton.addActionListener(new Deposit());
withdrawButton.addActionListener(new Withdraw());
...
class Deposit implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
balance++;
balanceDisplay.setText("" + balance);
}
}
...
class Withdraw implements ActionListener
...
}
The main program class no longer implements the ActionListener interface. The inner classes do instead. A single object of each class is created to act as a listener object for each button.