JFC is a "framework" for building graphical user interfaces. These include the classes in the java.awt and javax.swing packages, Java Accessibility, Java 2D, Java 3D, etc. A JFC GUI is a window containing GUI components such as buttons, menus, text fields, etc.. Here are a few of the JFC component classes:
Most GUI components fire events when manipulated by users. Here are a few JFC event classes:
For example, the reactor console indirectly extends JFrame and contains two JButtons and a JLabel:
When the user presses either the "inc" or "dec" button, an action event is fired and the corresponding reactor method is invoked. But how does the console know when an action event has been fired?
In JDK 1.0 every action event was routed to the other GUI components. Each component could either handle the event or ignore it. This scheme was inefficient because a lot of time was wasted routing the event to disinterested components.
In later versions of Java a strategy called event delegation was adopted. Under this scheme programmers were required to register listener objects with each component that fired events the programmer wanted to handle. When a component fires an event, the event is only routed to registered listeners. If there are no registered listeners-- if the programmer isn't interested in a particular event-- then no routing occurs. all listeners must realize one or more listener interfaces:
For example, in the reactor console constructor, an IncAction listener is added to the list of listeners for the "inc" button and a DecAction listener is added to the list of listeners for the "dec" button (these are the only listeners):
incButton.addActionListener(new IncAction());
decButton.addActionListener(new DecAction());
IncAction and DecAction are declared as inner classes of the ReactorConsole class. This is commonly done because these classes are seldom reusable outside of a particular GUI, but also because inner class instances have access to the private variables of the outer class instance that creates them. Thus, our listeners can access the myReactor reference of the reactor console that creates them:
class IncAction
implements ActionListener {
public void actionPerformed(ActionEvent
a) {
myReactor.inc(500);
}
}
class DecAction
implements ActionListener {
public void
actionPerformed(ActionEvent a) {
myReactor.dec(50);
}
}
Notice that this is yet another example of the Publisher-Subscriber pattern. Components are publishers. They publish events. Listeners are subscribers. They must implement methods prescribed by appropriate listener interfaces and they must register with the components they listen to. When an event is fired, the appropriate methods of every registered listener is called.