250 likes | 489 Views
Event-Driven Programming. Writing GUI applications requires a style of program control called event-driven programming. An event occurs when a user (like you) interacts with a GUI object (like a JButton). Spy++ Demo.
E N D
Event-Driven Programming CS-1020 Dr. Mark L. Hornick
Writing GUI applications requires a style of program control called event-driven programming • An event occurs when a user (like you) interacts with a GUI object (like a JButton) CS-1020 Dr. Mark L. Hornick
Spy++ Demo • Spy++ is a utility for snooping on events that are generated within Windows CS-1020 Dr. Mark L. Hornick
Event-driven programs… …contain two special types of objects: • Event source objects - GUI objects (like JButton) which generate the events • When an event is generated, the operating/windowing system captures the generated event • Event listener objects • Subscribe to the operating/windowing system to be notified when certain events occur CS-1020 Dr. Mark L. Hornick
OS Event Handling When the operating system captures an event, it notifies a subscribed event listener object by calling the event listener’s event handling method • If no event listener object is subscribed to listen for an event, the events from the event source object are ignored CS-1020 Dr. Mark L. Hornick
There are many types of Events • One of the most common is an Action Event CS-1020 Dr. Mark L. Hornick
Handling Action Events • An object that can be registered as an Action Listener (i.e. can subscribe to Action Events) must be an instance of a class that is declared specifically for the purpose • That is, it the class must implement the ActionListener interface • To subscribe an Action Listener to an Action Event source, the event source’s addActionListener method must be called with a reference to the Action Listener object as its argument. • i.e. JButton has an addActionListener() method:JButton btnQuit = new JButton(“Quit”); btnQuit.addActionListener( eventHandler ); // eventHandler is an ActionListener CS-1020 Dr. Mark L. Hornick
ActionListener is a Java interface Recall: Any class that implements a Java interface must provide the method body to all the methods defined in the interface • The ActionListener interface only defines a single method – actionPerformed() CS-1020 Dr. Mark L. Hornick
Which class or classes should be Action Listeners? First alternative: 1. Have a separate class listen for events This separates GUI creation and event handling • Could be good if there is a lot of non-GUI logic involved in responding to events CS-1020 Dr. Mark L. Hornick
Defining a separate class that implements ActionListener: import java.awt.event.*; class EventHandler implements ActionListener { ... public void actionPerformed( ActionEvent evt ){ ... } } The system notifies an Action Listener by calling the listener’s actionPerformed() method • The actionPerformed() method is passed a single argument: • a reference to an ActionEvent object CS-1020 Dr. Mark L. Hornick
We need to handle events from multiple sources… A single Action Listener can be subscribed to multiple event sources (e.g. many buttons) • The Action Listener must be able to distinguish one source from another CS-1020 Dr. Mark L. Hornick
Determining an event source – method 1: by event object • First, we use the Java instanceof operator to determine the class to which the event source belongs: public void actionPerformed( ActionEvent evt ){ if (evt.getSource() instanceof JButton ){ //event source is a button (but which one??) ... } else if (evt.getSource() instanceof JTextFrame ) { //event source is a JTextFrame (but which one??) ... } CS-1020 Dr. Mark L. Hornick
Once we know the Class of the item that generated the event… • …we use the getSource() method to return a reference to the Object that generated the event: if( evt.getSource() instanceof JButton ){ JButton btn= (JButton) evt.getSource(); • Note that the getSource returns a reference to an object of the class Object • An Object reference can refer to any type of class, so we typecast the returned Object reference to a JButton reference in order to be able to access JButton methods. CS-1020 Dr. Mark L. Hornick
Identifying the specific event object • Once you know that the source was a JButton, you can check the source against your program’s inventory of JButton objects: if (evt.getSource() instanceof JButton ){ //event source is a button (but which one??) JButton btn = (JButton)evt.getSource();if( btn == btnQuit ) … else if( btn == btnCancel ) … } CS-1020 Dr. Mark L. Hornick
Determining an event source – method 2: by action command • The event’s getActionCommand() method can be used to get the text of the object’s Action Command that generated the event: String command = evt.getActionCommand(); if(command.equals(“Quit”) // the Quit button ... else if( command.equals(“Cancel”) // Cancel button • By default, the Action Command text is the same as the text that appears on the button face (for a JButton) or the text with a JTextField • So what do you do if the button does not contain text? • And a user can enter just about any text into a JTextField CS-1020 Dr. Mark L. Hornick
setActionCommand method • The setActionCommand() method can be used to set the Action Command text for any component btnQuit = new JButton ("Quit"); btnQuit.setActionCommand(“Close”); textDate = new JTextField(); textDate.setActionCommand(“Begin”); • The text of the Action Command is up to you • Calling setActionCommand() does not change the text on the button face or within the text field (that’s done with setText() ) CS-1020 Dr. Mark L. Hornick
Multiple Action Event handlers • Likewise, multiple Action Listeners can be subscribed to a single event source. • When an event source generates an event, the system notifies all matching registered ActionListeners • Using multiple listeners is not very common CS-1020 Dr. Mark L. Hornick
Some consequences of implementing a separate class for Action Listeners • GUI creation and event handling are separated • Could be good if there is a lot of non-GUI logic involved in responding to events • We could separate event handling into several classes in order to avoid all the if and instanceOf logic for determining the event source • The Action Listener classes can’t access the variables that reference GUI objects • unless the objects are public (not a good approach) • or public accessor methods are provided to access each UI component (good, but that could lead to a lot of accessors) CS-1020 Dr. Mark L. Hornick
Which class or classes should be Action Listeners? Second alternative: • Have the class that created the GUI in the first place listen for all events • GUI creation and event handling all in a single class • But still lots of if statements and instanceOf checks inside the actionPerformed method CS-1020 Dr. Mark L. Hornick
UML Sequence Diagram CS-1020 Dr. Mark L. Hornick
Which class or classes should be Action Listeners? Third alternative: • Use separate inner classes to listen for events • GUI creation and event handling separated • Could be good if there is a lot of non-GUI logic involved in responding to events • Could separate event handling into several classes in order to avoid all the if and instanceOf logic for determining the event source • The Action Listener inner classes CAN access the variables that reference GUI objects (keeping the objects private) CS-1020 Dr. Mark L. Hornick
What’s an inner class? • An inner class is another class defined inside the same java file - inside the enclosing class import java.awt.event.*; class MyGUIClass { // create GUI and implement usual methods here // define an inner class for handling events class AnActionListener implements ActionListener { public void actionPerformed( ActionEvent evt ){ // handle events here }} // end of inner class } // end of enclosing class CS-1020 Dr. Mark L. Hornick
Inner class properties • The inner class can access all the members (public or private) of the enclosing class • The inner class is private to the outside world • You can’t create an instance of an inner class – only the enclosing class • You can have any number of inner classes CS-1020 Dr. Mark L. Hornick
Handling events • Multiple Action Listeners can handle multiple related events • This varies according to the judgment of the program designers CS-1020 Dr. Mark L. Hornick
Performance Issues • Event-handling code executes in an single thread, the event-dispatching thread. This ensures that each event handler finishes execution before the next one executes. • Painting code also executes in the event-dispatching thread. Therefore, event-handling code should execute quickly so that the program’s GUI stays responsive. If an event takes too long to execute, the GUI will freeze--that is, it won’t repaint or respond to mouse clicks. CS-1020 Dr. Mark L. Hornick