The ability to extend an existing class is one of the most powerful features of object-oriented programming. It allows objects to reuse code defined in the superclasses without having to redefine or recompile the code.
In this section, we will use inheritance to design a ToggleButton as a JButton subclass. As its name suggests, it will toggle its label whenever it is clicked, in addition to carrying out some kind of associated action. It will behave like a light switch, toggling between “on” and “off” as it turns the lights on or off.
Subsection8.4.1The ToggleButton class
By default, a JButton has just a single label. The main idea in our design is that a ToggleButton is a JButton that has two labels, as in Figure 8.4.1.
Note that we give it a constructor method that will allow us to provide the initial values of its labels. Another important feature is that it implements the ActionListener interface, which will enable it to toggle its label whenever it is clicked.
The complete definition of ToggleButton is given in Listing 8.4.2.
Note how we have defined its constructor. Recall that a subclass constructor must call its superclass constructor. In this case we call super(l1), setting the JButton label through the first of the two ToggleButton labels. This initializes the button’s label. This will be the label that appears on the button when it is first displayed.
Notice also in the constructor that the ToggleButton adds itself as its own ActionListener, so whenever it is clicked, its actionPerformed() method will be invoked.
The actionPerformed() method toggles between label1 and label2 and uses the inherited setText() method to set the buttons label to label1.
Swapping two values in memory is a standard programming practice used in lots of different algorithms. It requires a temporary variable, as described in the following algorithm.
Algorithm8.4.3.Algorithm to Swap var1 and var2.
temp = var1
var1 = var2
var2 = temp
Consider the following trace of the algorithm, where var1 and var2 are integers:
Now that we have seen that a ToggleButton toggles its label between two values, what about performing an associated action? To do this, we will need multiple event handlers, one to handle the toggling of the button’s label and the other to handle its associated action (Fig 8.4.5).
In this design, one listener is associated with the ToggleButton itself and the other with the object that uses the ToggleButton.
The implementation of this design is given by LightSwitchTester (Listing 8.4.6). LightSwitchTester extends JFrame and implements the ActionListener interface. The ToggleButton (named lightSwitch) simulate a light switch. Whenever it is pressed, the LightSwitchTester will report whether the light is on or off and the lightSwitch will toggle its label.
When lightSwitch is clicked, the program displays the message, “The light is on,” or “The light is off,” in the program’s title bar (Figure 8.4.7). This is a somewhat trivial action but it illustrates that a ToggleButton both toggles its own label and carries out some associated action.
The ToggleButton design satisfies several key design principles of object-oriented programming. First and foremost, it uses inheritance to extend the functionality of the predefined JButton class—the extensibility principle. Secondly, it encapsulates a ToggleButton’s essential behavior within the ToggleButton class itself—the modularity principle. Finally, it hides the mechanism by which a ToggleButton manages its labels—the information-hiding principle.
Principle8.4.8.EFFECTIVE DESIGN: Inheritance.
Inheritance enables you to specialize an object’s behavior. A ToggleButton does everything that a JButton does, plus it can toggle its own label.
Suppose you are designing an GUI that plays a card game, and you want a single button that can be used both to deal the cards and to collect the cards. Write a code segment that creates this type of button, adds it to the JFrame, and designates the JFrame as its ActionListener.