“Listeners” Overview Picture: +---------------------------------------------------------------+ | Operating System detects some “event” of interest. An Event | | object of the appropriate class is then constructed and passed| | as an argument to some listener object that is “associated” | | with the component about which the event is related. | +---------------------------------------------------------------+ \ \ <?>Event passed as param. V Implements some Interface +-------------+ call to +-------------+ | Some | add<?>Listener | <?>Listener |--Methods that | Component |---------------->| Object | are called | Object | forms this | | when event occurs. +-------------+ association +-------------+ In the above picture the <?> could be “Action”, “Item”, “Mouse”, “Window” or one of several others! Different events are detected and passed to a listener depending on the kind of component and triggering event. Listener ActionListener Component Button TextField MenuItem List Triggering Event Button is clicked. Enter Key hit The menu item is selected An item in list is double clicked ItemListener List Choice Checkbox CheckboxMenuItem An item in list is single clicked An Item is selected from the drop down list The box is either checked or unchecked The checkbox menu item is checked or unchecked TextListener TextField or TextArea User enters some key while in this component WindowListener Window Window is activated or deactivated Window is iconified or deiconified Window is opened or closed Window is closing MouseListener Any Component! Mouse button pressed in given component Mouse button released in given component Mouse button clicked in given component [this equals pressed + released] Mouse enters the given component (passing over) Mouse exits the given component (after above) +Others for clicking and dragging a component FocusListener Any Component! Given component gains or loses “focus” [We “go” there by tabbing or by mouse click] Listeners (Ch. 11- 13), page 1 As implied from the above chart, some components could have multiple listeners associated with them (by addListener method calls). For example, a Button could have an ActionListener to respond when the button is clicked and a MouseListener to respond when the mouse passes over the button. When an event is sent to a listener one of the listeners method is invoked depending on which triggering event occurred. This relationship is shown in the table below: Listener Interface Methods ActionListener actionPerformed(ActionEvent ev) ItemListener itemStateChanged(ItemEvent ev) Could use ev.getStateChange() which returns an int to figure out the change. Returned int is either: ItemEvent.SELECTED or ItremEvent.DESELECTED TextListener textValueChanged(TextEvent ev) WindowListener windowActivated(WindowEvent ev) windowDeactivated(WindowEvent ev) windowIconified(WindowEvent ev) windowDeiconified(WindowEvent ev) windowOpened(WindowEvent ev) windowClosed(WindowEvent ev) windowClosing(WindowEvent ev) MouseListener mousePressed(MouseEvent ev) mouseReleased(MouseEvent ev) mouseClicked(MouseEvent ev) [combo of above two] mouseEntered(MouseEvent ev) mouseExited(MouseEvent ev) FocusListener focusGained(FocusEvent ev) FocusLost(FocusEvent ev) Could use ev.isTemporary() (a boolean method) to see if focus change is “permanent” (i.e. we got here by a mouse click or a tab key). For ALL Events we can use “ev.getSource()” – which returns an Object, to determine the particular component that caused the triggering of the event. This is most useful when a given listener is acting on behalf of several objects. For example, if we have one ActionListener working for button1 and button2 objects, then inside of that actionPerformed method we might see code like: if (ev.getSource() == button1) { // Code for button1 pressed else { // Code for button2 pressed } Listeners (Ch. 11- 13), page 2 Q: Who is this “Listener” anyway? A: Any object who promises to implement the specified listener interface! There are several ways that this can be accomplished. We will demo 3 of them below. While this example below focuses on three ways to do the ActionListener the same examples would work for other kinds of listeners as well. Assume we want to put a Button (say button1) onto a Frame (say of class Frame1). Solution 1: (Use container as ActionListener) (a) public class Frame1 extends Frame implements ActionListener { (b) button1.addActionListener(this); (c) In Frame1 class add method: public void actionPerformed(ActionEvent ev) In solution one the frame itself is acting as the listener for one or more of his components. The Frame1 class can only have one actionPerformed method, thus if the Frame1 object acts as listener for more than one of his components this same listener code would be used for ALL of them. Thus the listener would in essence be “shared” and within the listener we might need to use getSource() on the incoming parameter to determine which component caused a given call to occur. Solution2: (Use a specialized ActionListener inner class) (a) button1.addActionListener(new button1Listener()); (b) And then write an inner class inside of Frame1 class of the form: public class button1Listener implements ActionListener { public void actionPerformed(ActionEvent ev) { // Code here specifically for responding to button1 click! } } Solution 3: (Use an unnamed ActionListener class) (a) button1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { // Code here to respond to button1 being pressed. Response code here… } // End of actionPerfomed method } // End of un-named ActionListener class ); // End of call to addActionListener Comparison: Pro: Con: Solution 1 No new class files created for each listener as the listener is just a method of the container. The container can have only one listener of any given kind thus it might have to be “shared” if multiple components of that type wanted to use the container. Solution 2 or 3 Each listener is “specialized” for a given component, thus no need in the code to ask which component signaled the event. Each new class (inner or un-named) results in another “.class” file being created. This can result in a proliferation of “small” classes. Listeners (Ch. 11- 13), page 3