Component-Based Software Engineering The Java Event Model Paul Krause
Callbacks and Events Contents Callbacks Events Events in Java
Problems Pauls Pictures Pauls Documents Pauls Sums Pauls Pictures Pauls Homework Pauls Pictures Pauls Documents Pauls Sums Pauls Homework Pauls ToDo Lists
Window Library Client File System But I need to tell you I’m in charge something! I’m in charge here, guys! My Documents Reports Papers Presentations Client File System Slide Shows Calls
Callbacks Callbacks are used in procedural libraries when they need to handle asynchronous events The alternative is for the client to continuously poll the library for events This is inefficient, especially if a large number of library components are registered with a client But the use of callback means a client may observe “intermediate” states of a library “Classically” a library’s operations would run to completion before returning control
Call Sequence Client aUser Library Client installs callback Third party calls library “I need to tell you something!” Library invokes callback “What’s happened?” Callback queries library “He’s changed a name!” “That’s cool” Callback returns Library returns
Directory Service public class Directory { public void addEntry(String name, File file) { // pre name != “” and file != null // post File file = map.get(name) } public void removeEntry(String name) { // pre name != “” // post map.get(name) = nil public void registerNotifier(Notifier n) { // pre n != nil // post n registered, will be called on addEntry and removeEntry
Callbacks and Events Contents Callbacks Events Events in Java
Events An abstraction of Callback that is applicable to “federations” of interacting components The firing of an event is a way of one object telling one or more other recipients that something interesting has happened The sender fires an event A recipient is called a listener and handles the event
Register Event Listener Java Event Model Event Source Register Event Listener Fire Event Event Object Event Listener
Event Objects Encapsulates information specific to an instance of an event E.g. a “mouse click” event may contain: The position of the mouse pointer Which mouse button was clicked (and how many times) The event object is passed as a parameter to the event notification method
Event Listeners These are objects that need to be notified when a certain event occurs Event notifications are made through method invocations in the listening object The event object is passed as a parameter The event source must know which listener object(s) to call This information is contained in an event-listener interface
Event Sources Objects that fire events Implement methods that allow listeners to: Register their interest in the events they generate; Unregister their interest in the events they generate. Multicast event delivery enables an event to be fired to a number of event-listeners
invokes notifications in Summary EventObject source getSource() toString() passed to fires EventSource addListener() removeListener() EventListener notification(evt) registers 0..* invokes notifications in 0..*
Callbacks and Events Contents Callbacks Events Events in Java
Java Events An “Event” encapsulates information about some state change in its source Pressing a button Entering text in a text field Moving a slider on a scroll bar, … Events need not be generated by users: Expiration of a timer Arrival of incoming data, …
Event Sources An event source must: Provide methods to enable “listeners” to register and unregister interest in its events Fire the events, of course! “Send” each event to all listeners who are interested in that type of event For an event of Type, and listener e1: public void addTypeListener(TypeListener e1); removeTypeListener(TypeListener e1);
Listeners Have three responsibilities: Register for events of a certain Type Implement an interface to “receive” events of a certain Type Unregister if they no longer wish to receive events of Type
Events EventObject: AWTEvent: EventObject(Object source) Object getSource( ) String toString( ) AWTEvent: AWTEvent(Object source, int id) int getID( ) Object EventObject AWTEvent
Example: Temperature Converter // Event Source convertTemp = new JButton("Convert..."); … // Listen to events from Convert button. convertTemp.addActionListener(this); // Implementation of ActionListener interface. public void actionPerformed(ActionEvent event) { // Parse degrees Celsius as a double and convert to Fahrenheit. int tempFahr = (int)((Double.parseDouble(tempCelsius.getText())) * 1.8 + 32); fahrenheitLabel.setText(tempFahr + " Fahrenheit"); } //v 1.3 // Example taken from the Sun website: // http://java.sun.com/docs/books/tutorial/uiswing/mini/index.html import java.awt.*; import java.awt.event.*; import javax.swing.*; // This example demonstrates the use of JButton, JTextField // and JLabel. public class CelsiusConverter implements ActionListener { JFrame converterFrame; JPanel converterPanel; JTextField tempCelsius; JLabel celsiusLabel, fahrenheitLabel; JButton convertTemp; // Constructor public CelsiusConverter() { // Create the frame and container. converterFrame = new JFrame("Convert Celsius to Fahrenheit"); converterFrame.setSize(40, 40); converterPanel = new JPanel(); converterPanel.setLayout(new GridLayout(2, 2)); // Add the widgets. addWidgets(); // Add the panel to the frame. converterFrame.getContentPane().add(converterPanel, BorderLayout.CENTER); // Exit when the window is closed. converterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Show the converter. converterFrame.pack(); converterFrame.setVisible(true); } // Create and add the widgets for converter. private void addWidgets() { // Create widgets. tempCelsius = new JTextField(2); celsiusLabel = new JLabel("Celsius", SwingConstants.LEFT); convertTemp = new JButton("Convert..."); fahrenheitLabel = new JLabel("Fahrenheit", SwingConstants.LEFT); // Listen to events from Convert button. convertTemp.addActionListener(this); // Add widgets to container. converterPanel.add(tempCelsius); converterPanel.add(celsiusLabel); converterPanel.add(convertTemp); converterPanel.add(fahrenheitLabel); celsiusLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); fahrenheitLabel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); // Implementation of ActionListener interface. public void actionPerformed(ActionEvent event) { // Parse degrees Celsius as a double and convert to Fahrenheit. int tempFahr = (int)((Double.parseDouble(tempCelsius.getText())) * 1.8 + 32); fahrenheitLabel.setText(tempFahr + " Fahrenheit"); // main method public static void main(String[] args) { // Set the look and feel. try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch(Exception e) {} CelsiusConverter converter = new CelsiusConverter();
Summary The components of a software product must interact to achieve a goal In general, it is hard to identify a single component that has overall control So a general model is for components to interact by triggering “Events” that other components register an interest in