Events Here, we review event handling one more time. To understand how events work in Java, we have to look closely at how we use GUIs. When you interact.

Slides:



Advertisements
Similar presentations
1 Graphical User Interface (GUI) Applications Abstract Windowing Toolkit (AWT) Events Handling Applets.
Advertisements

Event-Driven Programming Thus far, our programs have been executed one statement after the other However, many programs depend on user actions to dictate.
Graphical User Interface (GUI) Programming II. Lecture Objectives Understand the Event-Handling Processes in Java.
Graphical User Interface (GUI) Programming II. Lecture Objectives Understand the Event-Handling Processes in Java.
Event Handling. In this class we will cover: Basics of event handling The AWT event hierarchy Semantic and low-level events in the AWT.
Slides prepared by Rose Williams, Binghamton University Chapter 17 Swing I.
Events ● Anything that happens in a GUI is an event. For example: – User clicks a button, presses return when typing text, or chooses a menu item ( ActionEvent.
Event-Driven Programming Thus far, our programs have been executed one statement after the other However, many programs depend on user actions to dictate.
For IST410 Students only Events-1 Event Handling.
Event Handling n Events: an event is an object that describes a state change in a source. n Event Sources: A source is an object that generates an event.
Intermediate Java1 An example that uses inner classes Week Four Continued.
1 lecture 12Lecture 13 Event Handling (cont.) Overview  Handling Window Events.  Event Adapters Revisited.  Introduction to Components and Containers.
GUI Event Handling Nithya Raman. What is an Event? GUI components communicate with the rest of the applications through events. The source of an event.
Graphical User Interface CSI 1101 N. El Kadri. Plan - agenda Graphical components Model-View-Controller Observer/Observable.
MIT AITI 2003 Lecture 17. Swing - Part II. The Java Event Model Up until now, we have focused on GUI's to present information (with one exception) Up.
More Event Handling Adapters Anonymous Listeners Pop menus Validating User Input.
Java GUI’s are event driven, meaning they generate events when the user interacts with the program. Typical events are moving the mouse, clicking a mouse.
Liang, Introduction to Java Programming, Sixth Edition, (c) 2007 Pearson Education, Inc. All rights reserved Chapter 14 Event-Driven Programming.
(c) University of Washington07b-1 CSC 143 Java Events, Event Handlers, and Threads Reading: Ch. 17.
Slides prepared by Rose Williams, Binghamton University ICS201 Lecture 13 : Swing I King Fahd University of Petroleum & Minerals College of Computer Science.
1 Outline 1 Introduction 2 Overview of Swing Components 3 JLabel 4 Event Handling 5 TextFields 6 How Event Handling Works 7 JButton 8 JCheckBox and JRadioButton.
Graphic User Interface. Graphic User Interface (GUI) Most of us interact with computers using GUIs. GUIs are visual representations of the actions you.
Graphics and Event-Driven Programming in Java John C. Ramirez Department of Computer Science University of Pittsburgh.
COMP 321 Week 2. Outline Event-Driven Programming Events, Event Sources, Event Listeners Button and Timer Events Mouse Events, Adapters.
Pravin Yannawar, DOCS, NMU Jalgaon. Basic Java : Event handling in AWT and Swing 2 Objectives of This Session Explain the Event handling mechanism & demonstrate.
Software Design 5.1 From Using to Programming GUIs l Extend model of "keep it simple" in code to GUI  Bells and whistles ok, but easy to use and hide.
Creating a GUI with JFC/Swing. What are the JFC and Swing? JFC –Java Foundation Classes –a group of features to help people build graphical user interfaces.
UID – Event Handling and Listeners Boriana Koleva
Event Handling. 2 GUIs are event driven –Generate events when user interacts with GUI e.g., moving mouse, pressing button, typing in text field, etc.
CS-1020 Dr. Mark L. Hornick 1 Event-Driven Programming.
Anonymous Classes An anonymous class is a local class that does not have a name. An anonymous class allows an object to be created using an expression.
Object Oriented Programming.  Interface  Event Handling.
CSE 331 Software Design & Implementation Hal Perkins Autumn 2012 Event-Driven Programming 1.
Ch13 Creating windows and applets. Short overview AWT (Abstract Windowing Toolkit) Early Java development used graphic classesEarly Java development used.
GUI DYNAMICS Lecture 11 CS2110 – Fall GUI Statics and GUI Dynamics  Statics: what’s drawn on the screen  Components buttons, labels, lists, sliders,
CIS Intro to JAVA Lecture Notes Set 8 9-June-05.
Event-Driven Programming CSCI 201L Jeffrey Miller, Ph.D. HTTP :// WWW - SCF. USC. EDU /~ CSCI 201 USC CSCI 201L.
Event-Driven Programming F Procedural programming is executed in procedural order. F In event-driven programming, code is executed upon activation of events.
What Is an Event? Events – Objects that describe what happened Event sources – The generator of an event Event handlers – A method that receives an event.
CSI 3125, Preliminaries, page 1 Event Handling. CSI 3125, Preliminaries, page 2 Event Handling An Event Change in the state of an object is known as event.
Mouse Events GUI. Types of Events  Below, are some of the many kinds of events, swing components generate. Act causing EventListener Type User clicks.
Event Handling and Listeners in SWING The practice of event handling.
Chapter 10 - Writing Graphical User Interfaces1 Chapter 10 Writing Graphical User Interfaces.
Lesson 28: More on the GUI button, frame and actions.
Sep 181 Example Program DemoTranslateEnglishGUI.java.
5-1 GUIs and Events Rick Mercer. 5-2 Event-Driven Programming with Graphical user Interfaces  Most applications have graphical user interfaces to respond.
TENTH LECTURE Event and listener. Events and Listeners An event can be defined as a type of signal to the program that something has happened. The event.
1 DemoBasic_v3, DemoBasic_v4 JButton JLabel. 2 Registering an ActionListener Register by invoking the following from within constructor DemoBasicFrame.
Event Driven (Asynchronous) Programming. Event handling in Unity Subclass a class that contains event handling methods, and then override those methods.
1 A Quick Java Swing Tutorial. 2 Introduction Swing – A set of GUI classes –Part of the Java's standard library –Much better than the previous library:
Prepared by: Dr. Abdallah Mohamed, AOU-KW Unit7: Event-driven programming 1.
A Quick Java Swing Tutorial
CSC 205 Programming II Lecture 5 AWT - I.
Events and Event Handling
Graphical User Interfaces
Chapter 14 Event-Driven Programming
Welcome To java
CHAPTER Reacting to the user.
Chapter 12 Event-Driven Programming
Event Handling Chapter 2 Objectives
Graphical User Interface (GUI) Programming II
A Quick Java Swing Tutorial
GUI Event Handling Nithya Raman.
GUI Programming III: Events
Event-driven programming for GUI
Introduction to Computing Using Java
Chapter 16 Event-Driven Programming
A Quick Java Swing Tutorial
Events, Event Handlers, and Threads
Programming Graphical User Interface (GUI)
Presentation transcript:

Events Here, we review event handling one more time. To understand how events work in Java, we have to look closely at how we use GUIs. When you interact with a GUI, there are many events taking place each second. Only a few of these, however, may actually be ‘delivered’ to the application.

Events Java uses a “delegation” event model found in many other toolkits. componentsevents listeners registration Under the delegation model, components fire events, which can be caught and acted on by listeners. A listener is linked to a component through a registration process. delegation eventevent filtration model The delegation event model is contrasted to an event filtration model where all events are delivered to target components regardless of whether they asked for them.

General Overview Recall our first consideration of events, where our first frame would not close, even when the end of main() was reached. We explained this behavior by thinking of our program as entering an “infinite loop” when the graphics are shown. This ‘infinite loop’ is actually an event-driven cycle, but we can think of it as a “while (true)” structure that periodically polls for user input.

The Real Story import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI We usually think of our program as a single, linear set of steps being executed. But something special happens when we create graphical objects.

The Real Story import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI When Java sees that you’ve created a GUI, your program gets a second “set” of linear instructions. This is actually a separate “thread”, but don’t worry if that’s unclear for now. We can think of this as a second part of our program than handles special graphics- related tasks (such as drawing the window, etc.)

Graphics Thread import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI Both of these “threads” are your program. You coded one of the lines of control. Java provides the other one. That way, things appear to happen simultaneously--your code executes and the window gets redrawn, refreshed, etc. Java quickly switches between your code and the graphics drawing code, so that both threads appear to execute at the same time.

import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI Don’t Panic Don’t worry if this “thread” stuff is confusing. Other classes go into this in detail. For our purposes, we only have to understand that there are two areas of a graphic program. 1 The code we wrote in main() and other methods 2 The code Java provides to handle the graphics side of things. Graphics Your Code

Who Cares? import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI This model is very important to understand because as it turns out, when an event occurs--such as mouse click, it happens in the “graphics side” of the model. Mouse Click occurs The code trapping this event appears in the graphics thread Actually, there’s a separate “event queue” that handles incoming events. But this is already complicated enough. Let’s just generalize and imagine that all events arrive in the ‘graphics side’ of things.

“Call backs” import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI Since the event arrived in the ‘graphics half’ of our program, we need a way to have it call a method in our program. This is known as a “call back”. callback Our event handling code The code trapping this event appears in the graphics thread

How? import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI callback So Java needs to call some event handling code that we write. The trouble is, how will Java know what we called out method? We can name them anything we want, and Java won’t necessarily know what methods handle events. But Wait! We can use interfaces, right?

Event Interfaces Java uses interfaces as its primary event handling scheme. If you implement an event-related interface, Java will know which methods to call. This is because the contract nature of interfaces requires all methods to appear in the implementing class. import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI callback public void actionPerformed (ActionEvent e) { // code doing something } This method MUST be there, so Java knows it can “callback” to it ActionListener

Why “Delegation”? “delegate” Since any class can implement any interface, we can have just about any object handle the events. We can therefore “delegate” event handling to this object. Remember MVC? Some (smart) folks believe you should organize where the events get handled. (This is the “controller” aspect to MVC.) M C V

Why “Registration”? We are told that “event registration” must occur before event handling will occur. What does this mean? Well, since we can have any class handle events, we need to tell Java which object implements the proper event handling interface. This “registers” the component as being interested in receiving callbacks. import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI Where to callback?

Another example public class DemoFrame extends Frame { public DemoFrame( ) { super (“A poor use of inheritance, but simple”); Handler2 h = new Handler2(); this.setSize(400,400); this.setLayout(new FlowLayout()); Button b = new Button (“Click me”); this.add(b); this.show(); } // Constructor public static void main(String args[]) { DemoFrame df; df = new DemoFrame(); } // main } // DemoFrame

Another example public class Handler2 implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println (“Button was clicked”); } } // Handler2 Why doesn’t this work?

Another example public class DemoFrame extends Frame { public DemoFrame( ) { super (“A poor use of inheritance, but simple”); Handler2 h = new Handler2(); this.setSize(400,400); this.setLayout(new FlowLayout()); Button b = new Button (“Click me”); b.addActionListener(h); this.add(b); this.show(); } // Constructor public static void main(String args[]) { DemoFrame df; df = new DemoFrame(); } // main } // DemoFrame

Question... We said we had to have a Listener to handle the event and it had to be an object. Does it have to be a separate object?

Another example public class DemoFrame extends Frame implements ActionListener { public DemoFrame( ) { super (“A poor use of inheritance, but simple”); Handler2 h = new Handler2(); this.setSize(400,400); this.setLayout(new FlowLayout()); Button b = new Button (“Click me”); b.addActionListener(this); this.add(b); this.show(); } // Constructor public void actionPerformed(ActionEvent e) { System.out.println (“Button was clicked”); } public static void main(String args[]) { DemoFrame df; df = new DemoFrame(); } // main } // DemoFrame

Questions?

This program has performed an illegal instruction and will be shutdown. Please shell out another $200 for a more stable version of this OS. BSOD

Just Kidding Anything can be an event. Including general protection faults. But for the most part, good programming dictates that handled events should come from the following area of input: Keyboard events Timing events Mouse events Other user action inputs a b c d

Java Event Handling Strategies With this basic understanding, we can investigate the FOUR FOUR primary means of event handling in Java Event Adapters Semantic Events Event Listeners Inheritance-based event handling Very similar Very general Very old You are 100% guaranteed to have a quiz question on this

ListenersStrategy No. 1 From the discussion about callbacks, we noted that interfaces were the primary mechanism for structuring our event handling. There are numerous event interfaces we can implement, roughly divided around categories of events. The next slide lists many of them. Don’t freak out because there are so many. We’ll highlight the most commonly used ones...

Most commonly used Yikes. So Many Choices Package java.awt.event features: ActionListener MouseListener MouseMotionListener AdjustmentListener ComponentListener FocusListener ContainerListener ItemListener KeyListener WindowListener TextListener As it turns out, the ActionListener is part of the “semantic” event group, even though it’s an interface. So let’s focus on simple events like MouseListener...

MouseListener The MouseListener interface has several methods we have to code: public void mouseClicked(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } -- a timing-based determination; else the events are processed as the events are processed as pressed/releases pressed/releases public void mouseEntered(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } -- entry into component public void mouseExited(MouseEvent e) { } public void mouseExited(MouseEvent e) { } -- exit from component public void mousePressed(MouseEvent e) { } public void mousePressed(MouseEvent e) { } -- simply a press... public void mouseReleased(MouseEvent e){ } public void mouseReleased(MouseEvent e){ } the corresponding release

import java.awt.*; import java.awt.event.*; public class MouseFrame implements MouseListener{ Color highlight, normal; boolean bHighlight = true; Frame fr; public MouseFrame () { fr = new Frame(“For demonstration only”); highlight = Color.red; normal = Color.gray; frame.setSize(400,400); Button b = new Button("Click"); b.addMouseListener(this); fr.setBackground(normal); fr.setLayout(new FlowLayout()); fr.add(b); fr.show(); } public static void main(String[] args) { new MouseFrame(); } To keep it simple, we ignore WindowEvents Note that when we run this the constructor will run and terminate (more)

public void mouseReleased(MouseEvent e){ System.out.println ("Changing color"); if (bHighlight) frame.setBackground(highlight); else frame.setBackground(normal); bHighlight = !bHighlight; } public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} } // MouseFrame “click”

Event Listener Summary We need a class that implements the appropriate listener type. We need to “register” a component as interested in receiving events: XYZ addXYZListener ( ); Whatever listener we’re working with. E.g.: addMouseListener(this); addMouseMotionListener(myEventHandler);

There’s another strategy using “adapters”, using inheritance that could have saved us some trouble...Observations The “WindowListener” interface required numerous methods. But only one was important to us. All the rest were coded as “no-op” or no operation methods

Adapters public class MouseAdapter implements MouseListener { public void mouseClicked(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseReleased(MouseEvent e) {}} Java has built-in classes called “event adapters” that implement each of the various event listeners. But all of these methods are “no-ops”. WHY?Strategy No. 2

Key to Adapters: Inheritance Why a bunch of no-op methods? Well, if you subclass the adapter, your class IS-A type of event listener. And you then only have to override the one or two methods you care about. The rest can be inherited as “no-ops” MouseFrame MouseAdapter

Parent class takes care of these import java.awt.*; import java.awt.event.*; extends MouseAdapter public class MouseFrame extends MouseAdapter implements MouseListener{ Color highlight, normal; boolean bHighlight = true; Frame frame; public MouseFrame () { frame = new Frame(“For demonstration only”); highlight = Color.red; normal = Color.gray; frame.setSize(400,400); Button b = new Button("Click"); b.addMouseListener(this); frame.setBackground(normal); frame.setLayout(new FlowLayout()); frame.add(b); frame.show(); } public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {}

Example (cont’d) public void mouseReleased(MouseEvent e){ System.out.println ("Changing color"); if (bHighlight) frame.setBackground(highlight); else frame.setBackground(normal); bHighlight = !bHighlight; } public static void main(String[] args) { new MouseFrame(); } } // MouseFrame We override the one or two methods we care about Same behavior; less code; but we use up our single inheritance

import java.awt.*; import java.awt.event.*; public class MouseFrame extends MouseAdapter { Color highlight, normal; boolean bHighlight = true; Frame frame; public MouseFrame () { frame = new Frame(“For demonstration only”); highlight = Color.red; normal = Color.gray; frame.setSize(400,400); Button b = new Button("Click"); b.addMouseListener(this); frame.setBackground(normal); frame.setLayout(new FlowLayout()); frame.add(b); frame.show(); } public void mouseReleased(MouseEvent e) { System.out.println ("Changing color"); if (bHighlight) frame.setBackground(highlight); else frame.setBackground(normal); bHighlight = !bHighlight; } public static void main(String[] args) { new MouseFrame(); } } // MouseFrame public class MouseAdapter implements MouseListener { public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} } This comes with Java!

Big Picture Time So far, we’ve tinkered(kurcalamak) with different ways of coding very low-level event handling. But what if our event handling needs are very general. Consider this simple dialog box: cancel Are you sure you wish to proceed ? There’s not much interaction that needs to be supported. Mouse entry/exit might not be needed at all. ok

Semantic Events public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} Wouldn’t it be convenient to abstract all of these small events into one “just-tell-me-when-its-clicked” event? public void actionPerformed(ActionEvent e) M1A1 Abstractor

Semantic Events Strategy No. 3 Semantic events provide a means of handling events at the component level. That is, you will not address fine-grained events like mouse entry and exit. Instead, you’ll only receive a callback when the component has received some type of input event

Semantic Events ALLFOUR Note: ALL input is sent into one of these FOUR categories. Semantic EventComponents and Firing Event ActionEventButton (activated) List (double-clicked) MenuItem (selected) TextField (typed) AdjustmentEventScrollbar (moved) ItemEventCheckbox (toggled) CheckboxMenuItem (selected) Choice (selected) List (selected) TextEventTextComponent (text changes) There are numerous event handlers for low-level events associated with these widgets.

Example import java.awt.*; import java.awt.event.*; public class MouseFrame extends Frame implements ActionListener { Color highlight, normal; boolean bHighlight = true; public MouseFrame () { highlight = Color.red; normal = Color.gray; this.setSize(400,400); Button b = new Button("Click"); b.addActionListener(this); this.setBackground(normal); this.setLayout(new FlowLayout()); this.add(b); this.show(); }

Example (cont’d) public void actionPerformed(ActionEvent e){ System.out.println ("Changing color"); if (bHighlight) this.setBackground(highlight); else this.setBackground(normal); bHighlight = !bHighlight; } public static void main(String[] args) { new MouseFrame(); } } // MouseFrame We therefore lose the ability to handle very fine- grained events (e.g., mouse entry/exit). But that might be acceptable for certain applications.

An earlier version of Java used “boolean” return values to indicate consumption of events. Events were delivered to components whether or not they registered for events. Not recommended; still used for some web development not Do not mix JDK 1.1 and JDK 1.02 event handlers--the component ceases to function! Rare use: JDK 1.02 guarantees which event will arrive first to a component. More common use: some browsers only support JDK a very early version of Java that uses this model. Professional applet developers still use this technique. Many browsers are now supporting the JDK 1.1 event model. (non) Option #4: JDK 1.02 Events Strategy No. 4

Event Listeners (interfaces) Event Adapters (inheritance) Semantic Events Costs Benefits Must code all methods; wasteful no-ops result Uses up single inheritance opportunity Simplifies event handling Loss of granular control; linear code Keep all events in single class Good abstraction; override those methods you need Event Handling Options: How to Decide

Debugging re: Event Handlers Debugging an event-driven program (whether applet or graphical application) is more tricky than debugging a non-event-driven program. With an event-driven Java program, you don't explicitly code any kind of event-handling loop that "polls" for occurring events, then calls the appropriate handler(s) for those events. Instead, the Java internals handle this polling action for you. Debugging becomes trickier because now you have to make sure that your event handling code works correctly. You also have to make sure you're handling the correct events in the first place! For example, your code for mouseEntered( ) may work perfectly, but if you're expecting it to get called when the user clicks a mouse button, it won't be!

Debugging re: Event Handlers So, in debugging event-driven programs written with Java, the steps are: Be sure you're handling the appropriate events: Map out on paper what events get thrown from what components, and what class(es) handle them. Handle the events appropriately: This is the kind of debugging you're already familiar with: Once you're sure the appropriate events are getting handled, the rest is being sure the event-handling code (and the code that the event handlers call) work.

To compare the three event handling techniques, let’s see a *brief* example how all three might work on a common problem. Events: A Short Example My Program BUTTON TEXT AREA Panel subclass Goal: Create a simple Frame that holds a TextArea and Button. The Button toggles the ability to edit the TextArea The Panel holding the Button and TextArea is placed in a Frame subclass, which handles its own disposal

import java.awt.*; import java.awt.event.*; public class MyFrame extends Frame implements WindowListener{ public static final int iWidth = 300, iHeight = 500; public MyFrame() { this.setSize(iWidth, iHeight); this.addWindowListener(this); BorderLayout border = new BorderLayout(); this.setLayout(border); } public void windowClosing (WindowEvent e) { e.getWindow().setVisible(false); e.getWindow().dispose(); System.exit(0); } public void windowActivated(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowOpened(WindowEvent e) {} }// class MyFrame Constructor WindowListener Frames are not self-disposing! (Setting Frame invisible first eliminate flicker.)

import java.awt.*; import java.awt.event.*; public class MyFrame extends Frame { public static final int iWidth = 300, iHeight = 500; public MyFrame() { this.setSize(iWidth, iHeight); this.addWindowListener (new WindowAdapter() { public void windowClosing (WindowEvent e) { e.getWindow().setVisible(false); e.getWindow().dispose(); System.exit(0); } }); BorderLayout border = new BorderLayout(); this.setLayout(border); } }// class MyFrame “Anonymous Inner Class”: used as a short cut. For your code, use listeners Frames are not self-disposing! (Setting Frame invisible first eliminate flicker.)

import java.awt.*; public class Driver { public static void main (String arg[]){ Notepad note = new Notepad(); MyFrame f = new MyFrame(); f.add(note, BorderLayout.CENTER); f.show(); }//main }//class Driver A simple driver. Notice that so far, we’ve abstracted the Frame subclass into something very generic and reusable--IT’S NOT JUST TIED TO THIS PROGRAM!

import java.awt.*; import java.awt.event.*; class Notepad extends Panel implements MouseListener { Button toggle; TextArea scratch; boolean bWritable; public Notepad() { super("Wasted inheritance"); this.setLayout (new BorderLayout()); scratch = new TextArea(20,20); Panel buttonPanel = new Panel(); toggle = new Button ("Freeze/Unfreeze"); buttonPanel.add(toggle); add(scratch, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); toggle.addMouseListener(this); bWritable = false; }// constructor Variation #1: Listener Events (MouseListener) The Driver and MyFrame classes were generic enough to work with any version of this example. Here, however, we need to create a specific event handler.

/*... Continued from “class Notepad extends Panel implements MouseListener”... */ public void setWritable(boolean bWritable){ this.bWritable = bWritable; }//setWritable public boolean getWritable() { return bWritable; }//getWritable public TextArea getTextArea(){ return scratch; }//getTextArea public void mousePressed(MouseEvent e) { getTextArea().setEnabled(getWritable()); setWritable(!getWritable()); }//mousePressed public void mouseReleased(MouseEvent e) {;} public void mouseClicked(MouseEvent e) {;} public void mouseEntered(MouseEvent e) {;} public void mouseExited(MouseEvent e) {;} }//class Notepad Implement the method one needs; the rest are “no-ops”

Driver main Notepad note MyFrame f Notepad extends Panel Button toggle TextArea scratch boolean bWritable My Program BUTTON TEXT AREA

Variation #2: Adapter Events (MouseAdapter) import java.awt.*; import java.awt.event.*; class Notepad extends Panel { /* NOTE: NO INTERFACE! */ Button toggle; TextArea scratch; boolean bWritable; public void setWritable(boolean bWritable){ this.bWritable = bWritable; }//setWritable public boolean getWritable(){ return bWritable; }//getWritable public TextArea getTextArea(){ return scratch; }//getTextArea

/*... Continued from “class Notepad extends Panel” */ public Notepad(){ super(); this.setLayout (new BorderLayout()); scratch = new TextArea(20,20); Panel buttonPanel = new Panel(); toggle = new Button ("Freeze/Unfreeze"); buttonPanel.add(toggle); add(scratch, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); toggle.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { getTextArea().setEnabled(getWritable()); setWritable(!getWritable()); } });/* end of anonymous inner class */ bWritable = false; }// constructor Note use of anonymous inner class.

Variation #3: Another Way! import java.awt.*; import java.awt.event.*; public class AnotherHandler extends MouseAdapter { Notepad np; public AnotherHandler(Notepad np) { this.np = np; } // Constructor public void mousePressed(MouseEvent e) { np.getTextArea().setEnabled(np.getWritable()); np.setWritable(!np.getWritable()); } } // AnotherHandler

Variation #3: Another Way import java.awt.*; import java.awt.event.*; class Notepad extends Panel { /* NOTE: NO INTERFACE! */ Button toggle; TextArea scratch; boolean bWritable; public void setWritable(boolean bWritable){ this.bWritable = bWritable; }//setWritable public boolean getWritable(){ return bWritable; }//getWritable public TextArea getTextArea(){ return scratch; }//getTextArea

/*... Continued from "class Notepad extends Panel" */ public Notepad(){ super(); this.setLayout (new BorderLayout()); scratch = new TextArea(20,20); Panel buttonPanel = new Panel(); toggle = new Button ("Freeze/Unfreeze"); buttonPanel.add(toggle); add(scratch, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); AnotherHandler ah = new AnotherHandler(this); toggle.addMouseListener(ah); bWritable = false; }// constructor

import java.awt.*; import java.awt.event.*; class Notepad extends Panel implements ActionListener { Button toggle; TextArea scratch; boolean bWritable; public Notepad(){ super(); this.setLayout (new BorderLayout()); scratch = new TextArea(20,20); Panel buttonPanel = new Panel(); toggle = new Button ("Freeze/Unfreeze"); buttonPanel.add(toggle); add(scratch, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); toggle.addActionListener(this); bWritable = false; }// constructor Variation #4: Semantic Events (ActionListener)

/*... Continued from "class Notepad extends Panel implements ActionListener"... */ public void setWritable(boolean bWritable){ this.bWritable = bWritable; }//setWritable public boolean getWritable(){ return bWritable; }//getWritable public TextArea getTextArea() { return scratch; }//getTextArea public void actionPerformed (ActionEvent e) { getTextArea().setEnabled(getWritable()); setWritable(!getWritable()); }//actionPerformed }//class Notepad

Event Handlers: Final Review This simple example shows that sometimes, semantic event handlers perform the task perfectly. In the drawing applet example, the semantic event handler was unable to offer help. In this example, it works perfectly, and was easier to follow and implement. Note that a few of the examples in this notepad demonstration used “anonymous inner classes”. You will not be required to use anonymous inner classes in this course; however, they are used a lot and if you have never seen them before they can be startling...be prepared.

Cross Class Communication Working with events often requires us to have “upstream” references, so that event handlers can call methods in the classes that created them.

Another (Familiar?) Example To illustrate cross-class communication,let’s make a simple program that’s similar the examples used in previous slides. We’ll use a Frame and a class to handle events. When the mouse enters a button, the button will flash, and will update the Frame’s title.

The Madness HAS-A Method EventHandler (a MouseListener) FlashDemo (a JFrame) Makes an array of JButtons sets their event handler, passing in “this” and the button. Saves the frame and button reference so it can call back to the frame to set its title, and change the button The two classes have to talk to each other, and therefore need references to each other.

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class FlashDemo extends JFrame implements WindowListener { JButton[][] buttons; public FlashDemo () { this.addWindowListener(this); buttons = new JButton[4][4]; JPanel panel = new JPanel(); panel.setLayout(new GridLayout(4,4,10, 10)); for (int i=0; i < buttons.length; i++) for (int j=0; j < buttons[i].length; j++){ buttons[i][j] = new JButton ("[" + i +"][" + j +"]"); EventHandler eh = new EventHandler (this, buttons[i][j]); buttons[i][j].addMouseListener(eh); panel.add(buttons[i][j]); } this.getContentPane().add(panel); this.setSize(350,350); } Key Method Call

/* class FlashDemo (cont’d) */ public void windowClosing(WindowEvent e) { System.exit(0); } public void windowActivated(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowOpened(WindowEvent e) {} public static void main (String[] arg){ new FlashDemo().show(); } } // FlashDemo

import java.awt.event.*; import java.awt.*; import javax.swing.*; public class EventHandler implements MouseListener { FlashDemo theFrame; JButton button; Color highlight; Color original; public EventHandler (FlashDemo theFrame, JButton button) { this.theFrame = theFrame; this.button = button; highlight = Color.yellow; original = button.getBackground(); } We SAVE reference to the frame that made this class, and the button it has to control

/* class EventHandler (cont’d) */ public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) { theFrame.setTitle ("You are now in Button #" + button.getLabel()); button.setBackground(highlight); } public void mouseExited(MouseEvent e) { theFrame.setTitle(""); button.setBackground(original); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} } // EventHandler

Additional Presentation...

Questions?