BM214E Object Oriented Programming Lecture 13

Similar documents
The AWT Event Model 9

Chapter 1 GUI Applications

Control Flow: Overview CSE3461. An Example of Sequential Control. Control Flow: Revisited. Control Flow Paradigms: Reacting to the User

Example Programs. COSC 3461 User Interfaces. GUI Program Organization. Outline. DemoHelloWorld.java DemoHelloWorld2.java DemoSwing.

GUI Program Organization. Sequential vs. Event-driven Programming. Sequential Programming. Outline

CSEN401 Computer Programming Lab. Topics: Graphical User Interface Window Interfaces using Swing

11/7/12. Discussion of Roulette Assignment. Objectives. Compiler s Names of Classes. GUI Review. Window Events

Java Graphical User Interfaces AWT (Abstract Window Toolkit) & Swing

GUI in Java TalentHome Solutions

Graphical Interfaces

G51PGP Programming Paradigms. Lecture 008 Inner classes, anonymous classes, Swing worker thread

Programming Languages and Techniques (CIS120e)

Graphical Interfaces

Outline. Topic 9: Swing. GUIs Up to now: line-by-line programs: computer displays text user types text AWT. A. Basics

GUI DYNAMICS Lecture July 26 CS2110 Summer 2011

Advanced Java Programming (17625) Event Handling. 20 Marks

GUI Programming: Swing and Event Handling

Java. GUI building with the AWT

Course: CMPT 101/104 E.100 Thursday, November 23, 2000

Java - Applications. The following code sets up an application with a drop down menu, as yet the menu does not do anything.

OBJECT ORIENTED PROGRAMMING. Java GUI part 1 Loredana STANCIU Room B616

Packages: Putting Classes Together

Unit 7: Event driven programming

SD Module-1 Advanced JAVA

Window Interfaces Using Swing Objects

SD Module-1 Advanced JAVA. Assignment No. 4

Window Interfaces Using Swing Objects

Graphical User Interfaces 2

Programming Mobile Devices J2SE GUI

Handling Mouse and Keyboard Events

Graphical User Interfaces 2

Graphical User Interfaces 2

Systems Programming Graphical User Interfaces

G51PRG: Introduction to Programming Second semester Applets and graphics

Swing from A to Z Some Simple Components. Preface

GUI Event Handling 11. GUI Event Handling. Objectives. What is an Event? Hierarchical Model (JDK1.0) Delegation Model (JDK1.1)

Java & Graphical User Interface II. Wang Yang wyang AT njnet.edu.cn

Graphic User Interfaces. - GUI concepts - Swing - AWT

Introduction to the JAVA UI classes Advanced HCI IAT351

GUI Event Handlers (Part I)

COMPSCI 230. Software Design and Construction. Swing

กล ม API ท ใช. Programming Graphical User Interface (GUI) Containers and Components 22/05/60

Programming Language Concepts: Lecture 8

CHAPTER 2. Java Overview

CS 2113 Software Engineering

Interacción con GUIs

CSE 143. Event-driven Programming and Graphical User Interfaces (GUIs) with Swing/AWT

CSSE 220. Event Based Programming. Check out EventBasedProgramming from SVN

UNIT-3 : MULTI THREADED PROGRAMMING, EVENT HANDLING. A Multithreaded program contains two or more parts that can run concurrently.

Lecture 19 GUI Events

Introduction to GUIs. Principles of Software Construction: Objects, Design, and Concurrency. Jonathan Aldrich and Charlie Garrod Fall 2014

User interfaces and Swing

Topic 9: Swing. Swing is a BIG library Goal: cover basics give you concepts & tools for learning more

Topic 9: Swing. Why are we studying Swing? GUIs Up to now: line-by-line programs: computer displays text user types text. Outline. 1. Useful & fun!

Starting Out with Java: From Control Structures Through Objects Sixth Edition

Method Of Key Event Key Listener must implement three methods, keypressed(), keyreleased() & keytyped(). 1) keypressed() : will run whenever a key is

CS11 Java. Fall Lecture 3

CSE 331 Software Design & Implementation

GUI Design. Overview of Part 1 of the Course. Overview of Java GUI Programming

Example: CharCheck. That s It??! What do you imagine happens after main() finishes?

KF5008 Program Design & Development. Lecture 1 Usability GUI Design and Implementation

Frames, GUI and events. Introduction to Swing Structure of Frame based applications Graphical User Interface (GUI) Events and event handling

(listener)... MouseListener, ActionLister. (adapter)... MouseAdapter, ActionAdapter. java.awt AWT Abstract Window Toolkit GUI

BASICS OF GRAPHICAL APPS

CONTENTS. Chapter 1 Getting Started with Java SE 6 1. Chapter 2 Exploring Variables, Data Types, Operators and Arrays 13

Event Driven Programming

Class 16: The Swing Event Model

CSE 331 Software Design and Implementation. Lecture 19 GUI Events

PIC 20A GUI with swing

Advanced Java Programming

Jonathan Aldrich Charlie Garrod

Graphical User Interfaces (GUIs)

Handout 14 Graphical User Interface (GUI) with Swing, Event Handling

(Incomplete) History of GUIs

Virtualians.ning.pk. 2 - Java program code is compiled into form called 1. Machine code 2. native Code 3. Byte Code (From Lectuer # 2) 4.

Table of Contents. Chapter 1 Getting Started with Java SE 7 1. Chapter 2 Exploring Class Members in Java 15. iii. Introduction of Java SE 7...

Java: Graphical User Interfaces (GUI)

State Application Using MVC

The Abstract Windowing Toolkit. Java Foundation Classes. Swing. In April 1997, JavaSoft announced the Java Foundation Classes (JFC).

Java AWT Windows, Text, & Graphics

The JFrame Class Frame Windows GRAPHICAL USER INTERFACES. Five steps to displaying a frame: 1) Construct an object of the JFrame class

CSE 331. Event-driven Programming and Graphical User Interfaces (GUIs) with Swing/AWT

MIT AITI Swing Event Model Lecture 17

Cheng, CSE870. More Frameworks. Overview. Recap on OOP. Acknowledgements:

Command-Line Applications. GUI Libraries GUI-related classes are defined primarily in the java.awt and the javax.swing packages.

Building Graphical User Interfaces. GUI Principles

Course Status Networking GUI Wrap-up. CS Java. Introduction to Java. Andy Mroczkowski

Dr. Hikmat A. M. AbdelJaber

Previously, we have seen GUI components, their relationships, containers, layout managers. Now we will see how to paint graphics on GUI components

Java Swing. Recitation 11/(20,21)/2008. CS 180 Department of Computer Science, Purdue University

Swing from A to Z Using Focus in Swing, Part 2. Preface

Lecture 5: Java Graphics

DM550 / DM857 Introduction to Programming. Peter Schneider-Kamp

COMP-202 Unit 10: Basics of GUI Programming (Non examinable) (Caveat: Dan is not an expert in GUI programming, so don't take this for gospel :) )

Introduction to concurrency and GUIs

University of Cape Town ~ Department of Computer Science. Computer Science 1016S / 1011H ~ November Exam

COSC 123 Computer Creativity. Graphics and Events. Dr. Ramon Lawrence University of British Columbia Okanagan

DM503 Programming B. Peter Schneider-Kamp.

SINGLE EVENT HANDLING

Together, the appearance and how user interacts with the program are known as the program look and feel.

Transcription:

BM214E Object Oriented Programming Lecture 13

Events 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. 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. 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 When Java sees that you ve created a GUI, your program gets a second set of linear instructions. 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 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 graphicsrelated 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.

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 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 2 The code Java provides to handle the graphics side of things. Your Code Graphics

Who Cares? 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. 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 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 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. Our event handling code 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 The code trapping this event appears in the graphics thread callback

How? 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. 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 But Wait! callback 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. ActionListener 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 public void actionperformed (ActionEvent e) { // code doing something } This method MUST be there, so Java knows it can callback to it callback

Why Delegation? 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. V C M Remember MVC? Some (smart) folks believe you should organize where the events get handled. (This is the controller aspect to MVC.)

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?

Event types 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: a Mouse events b Keyboard events c d Timing events Other user action inputs

Java Event Handling Strategies With this basic understanding, we can investigate the FOUR primary means of event handling in Java Very similar Very general Very old 1 2 3 4 Event Listeners Event Adapters Semantic Events Inheritance-based event handling

Listeners 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...

Yikes. So Many Choices Package java.awt.event features: ActionListener MouseListener MouseMotionListener AdjustmentListener ComponentListener FocusListener ContainerListener ItemListener KeyListener WindowListener TextListener Most commonly used 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) { } -- a timing-based determination; else the events are processed as pressed/releases public void mouseentered(mouseevent e) { } -- entry into component public void mouseexited(mouseevent e) { } -- exit from component public void mousepressed(mouseevent e) { } -- simply a press... 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(); } (more) To keep it simple, we ignore WindowEvents Note that when we run this the constructor will run and terminate

} 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

Event Listener Summary We need a class that implements the appropriate listener type. We need to register a component as interested in receiving events: addxyzlistener ( <listener instance> ); Whatever listener we re working with. E.g.: addmouselistener(this); addmousemotionlistener(myeventhandler);

Observations 1 2 3 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. There s another strategy using adapters, using inheritance that could have saved us some trouble...

Adapters Java has built-in classes called event adapters that implement each of the various event listeners. But all of these methods are no-ops. 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) {} } WHY?

Key to Adapters: Inheritance MouseAdapter MouseFrame 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

import java.awt.*; import java.awt.event.*; 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) {} Parent class takes care of these

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

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) {} } 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 This comes with Java!

Big Picture Time So far, we ve tinkered 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: Are you sure you wish to proceed? cancel ok There s not much interaction that needs to be supported. Mouse entry/exit might not be needed at all.

Semantic Events Wouldn t it be convenient to abstract all of these small events into one just-tell-me-when-its-clicked event? 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) {} M1A1 Abstractor public void actionperformed(actionevent e)

Semantic Events 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 Semantic Event Components and Firing Event ActionEvent AdjustmentEvent Button (activated) List (double-clicked) MenuItem (selected) TextField (typed) Scrollbar (moved) There are numerous event handlers for low-level events associated with these widgets. ItemEvent TextEvent Checkbox (toggled) CheckboxMenuItem (selected) Choice (selected) List (selected) TextComponent (text changes) Note: ALL input is sent into one of these FOUR categories.

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 finegrained events (e.g., mouse entry/exit). But that might be acceptable for certain applications.

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

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.

Events: A Short Example To compare the three event handling techniques, let s see a *brief* example how all three might work on a common problem. TEXT AREA BUTTON Goal: Create a simple Frame that holds a TextArea and Button. The Button toggles the ability to edit the TextArea Panel subclass My Program 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() { Frames are not self-disposing! (Setting Frame invisible first eliminate flicker.) 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

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!

Variation #1: Listener Events (MouseListener) 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 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 Implement the method one needs; the rest are no-ops 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

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

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); Note use of anonymous inner class. toggle.addmouselistener(new MouseAdapter() { public void mousepressed(mouseevent e) { gettextarea().setenabled(getwritable()); setwritable(!getwritable()); } });/* end of anonymous inner class */ bwritable = false; }// constructor

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

Variation #4: Semantic Events (ActionListener) 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

/*... 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 FlashDemo (a JFrame) EventHandler (a MouseListener) 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)); Key Method Call } 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);

/* 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

Questions?