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

G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

G51PGP

Programming Paradigms

Lecture 008

Inner classes, anonymous classes, Swing worker thread

1

Page 2: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Reminder – subtype polymorphism

public class TestAnimals

{

public static void main(String[] args)

{

Animal[] animals = new Animal[6];

animals[0] = new Bear();

animals[1] = new Mouse();

animals[2] = new Mouse();

animals[3] = new Fish();

animals[4] = new Mouse();

animals[5] = new Bear();

for ( int i = 0 ; i < animals.length ; i++ )

{

System.out.println( "" + animals[i].getName() +

" ... " + animals[i].getNoise() );

}

}

}2

Array of interface or object

references

Create objects and store

in the array

Each must implement

interface or extend class

The functions exist in ‘animal’ class or interface

Subclasses/implementers must provide implementations

Page 3: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Reminder : Interfaces

• Interfaces are just groups of

function declarations

– No implementations for functions

– We say that these functions are abstract

• A class may implement multiple

interfaces

3

Subclass /

Derived class

extends

implements

Superclass/base class

Interface

Base/superclassSub/derived class

public interface Animal

{

String getName();

String getNoise();

}

Page 4: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

A class hierarchy

• Some classes are both

sub-classes/derived

classes and

superclasses/base classes

4

Object

Component

Container

JComponent

JPanel

Window

Frame

JFrameJLabel

Page 5: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Abstract classes

• You can have abstract functions in classes

– Used only for implementing in the sub-classes

– E.g. abstract String getName();

• You can have abstract classes

– A class for which you cannot create objects

– E.g. public abstract class Animal { }

• If you add an abstract function to a class, the class must be declared abstract as well

• You can think of interfaces as abstract classes where all of the functions are abstract and there is no member data

– But you use implements rather than extends

– That matters: You can only extend one class, but can implement many interfaces

• We will concentrate on interfaces 5

Page 6: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

public interface Animal

{

String getName();

String getNoise();

}

• No need to say public

• No implementations

• No data

• Subclasses need to

implement the interface

• Classes may implement

multiple interfaces

public abstract class Animal

{

public abstract String getName();

public abstract String getNoise();

}

• We could mix abstract and

concrete methods

• We could add data

• Sub-classes need to extend the

class

• Classes can only extend one class

6

Interfaces

Page 7: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Event handlers

• Many window systems are event based

• Someone ‘does something’ and it raised an event for the program to handle– E.g. move the mouse, click on something, close a

window, etc

– More next week on what is picking up the events in Java

• Components can handle events– e.g. mouse move or mouse pressed

• When an event occurs, the components look whether they have an object registered to handle the event– Usually this means giving it an object which implements

the interface and we rely on subtype polymorphism7

Page 8: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

import java.awt.*;

import javax.swing.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

public class UsesButton

implements ActionListener

{

public static void main(

String[] args)

{

new UsesButton().go();

new UsesButton().go();

}

// Note: these were made members rather than local variables so that I keep the reference for later use

JFrame frame;

JLabel label;

JButton button;

public void go()

{

frame = new JFrame();

frame.setLayout( new FlowLayout() );

label = new JLabel( "." );

frame.add( label );

button = new JButton("Press Me");

button.addActionListener(this);

frame.add( button );

frame.pack();

frame.setVisible(true);

}

public void actionPerformed(

ActionEvent e)

{

label.setText(label.getText()+".");

frame.pack(); // Label size changed

}

}

8

Example using a JButton

New class: JButton

New interface: ActionListener

New function to add listener

Page 9: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

• To handle an event in

Java Swing, we provide

an object which will

handle the event

• We need an object

• The object must

implement a specified

interface

• The object must

implement all of the

functions in the

interface

public class UsesButton

implements ActionListener

{

public static void main( String[] args)

{

new UsesButton().go();

}

public void go()

{ …

button.addActionListener(this);

}

public void actionPerformed(

ActionEvent e)

{

label.setText(label.getText()+".");

frame.pack();

}

}9

Event handlers

Page 10: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

ActionListener interface

package java.awt.event;

import java.util.EventListener;

public interface ActionListener extends EventListener

{

/* Invoked when an action occurs. */

public void actionPerformed(ActionEvent e);

}

• This is the real code from the default implementation

• Reformatted, and most of the comments removed10

Page 11: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Listener interfaces and Observer Pattern

• Examples of something called an observer pattern

• You can register multiple listeners

• You can removeActionListener() to remove it again

• Action listeners get added to a list:

public void addActionListener(ActionListener l)

{

listenerList.add(ActionListener.class, l);

}

• Observer pattern:

– Object (subject) maintains a list of dependents (observers) and notifies them of specific events/changes

– Observers register themselves with the subject when they want to start getting notifications, and unregister themselves afterwards 11

Page 12: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Nested/Inner classes

• Nested class: class defined inside another class

• A static nested class is not associated with a specific instance of the class

– static basically means not associated with instance

– It just gets a different name really

– Useful for grouping or hiding implementation classes

– Static means associated with the class as a whole, rather than a specific object (no this reference on functions)

• A non-static nested class is an inner class

– It is associated with a specific instance/object

– It has access to the member data of the surrounding class – very useful at times

12

Page 13: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

import java.awt.*;

import javax.swing.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

public class UsesButtonInnerClass

{

public static void main(

String[] args)

{

new UsesButtonInnerClass().go();

new UsesButtonInnerClass().go();

}

// Still members…

JFrame frame;

JLabel label;

JButton button;

class ButtonPressHandler

implements ActionListener

{

public void actionPerformed(

ActionEvent e)

{

label.setText(label.getText()+".");

frame.pack(); // Label size changed

}

}

public void go()

{

frame = new JFrame();

frame.setLayout( new FlowLayout() );

label = new JLabel( "." );

button = new JButton("Press Me");

button.addActionListener(

new ButtonPressHandler());

frame.add( label );

frame.add( button );

frame.pack();

frame.setVisible(true);

}

} 13

Creating and using an inner class

Example2

Page 14: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

class ButtonPressHandler

implements ActionListener

{

public void actionPerformed(

ActionEvent e)

{

label.setText(

label.getText()+".");

frame.pack();

}

}

• Inner class

• Defined within the outer class

• Instances can access the members of

the surrounding instance – the one

which created it

public void go()

{

frame = new JFrame();

frame.setLayout(

new FlowLayout() );

label = new JLabel( "." );

frame.add( label );

button = new JButton(

"Press Me");

button.addActionListener(

new ButtonPressHandler());

frame.add( button );

frame.pack();

frame.setVisible(true);

}

14

Key features: new class and listening

Page 15: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

JButton button1; // Renamed

JButton button2; // Added

// Rename one handler

// and create a 2nd version

class ButtonPressHandler2

implements ActionListener

{

public void actionPerformed(

ActionEvent e)

{

label.setText( "." );

frame.pack();

}

}

public void go()

{

button1 = new JButton("Add");

button1.addActionListener(

new ButtonPressHandler1());

frame.add( button1 );

button2 = new JButton("Clear");

button2.addActionListener(

new ButtonPressHandler2());

frame.add( button2 );

15

Now we can create two buttons…

Example3

Page 16: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

MouseListener Interface

public interface MouseListener extends EventListener

{

/* Mouse button clicked (pressed and released) */

public void mouseClicked(MouseEvent e);

/* Mouse button has been pressed */

public void mousePressed(MouseEvent e);

/* Mouse button released */

public void mouseReleased(MouseEvent e);

/* Invoked when the mouse enters a component. */

public void mouseEntered(MouseEvent e);

/* Invoked when the mouse exits a component. */

public void mouseExited(MouseEvent e);

} 16

Page 17: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Using the interface : MyMouseHandler

class MyMouseHandler implements MouseListener

{

public void mouseClicked(MouseEvent e) {}

public void mousePressed(MouseEvent e) {}

public void mouseReleased(MouseEvent e) {}

public void mouseEntered(MouseEvent e) {}

public void mouseExited(MouseEvent e) {}

}

label.addMouseListener( new MyMouseHandler() );

17

Example4

Page 18: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

MouseMotionListener Interface

public interface MouseMotionListener extends EventListener

{

/* Mouse moved when button pressed */

public void mouseDragged(MouseEvent e);

/* Mouse moved when button not pressed */

public void mouseMoved(MouseEvent e);

}

18

Page 19: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Using the interface : MyMouseHandler

class MyMouseMotionHandler implements MouseMotionListener

{

/* Mouse moved when button pressed */

public void mouseDragged(MouseEvent e)

{ System.out.print("D"); }

/* Mouse moved when button not pressed */

public void mouseMoved(MouseEvent e)

{ System.out.print("M"); }

}

label.addMouseMotionListener( new MyMouseMotionHandler() );

19

Example4

Page 20: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Adapters• As interfaces become larger it may be a pain to implement all of the

functions when we only need a few (or one)

• Adapter classes solve this problem for us

• They already implement the interface and provide dummy implementations

for the functions – we just need to implement the ones which will change

class MyMouseHandler implements MouseListener

{

public void mouseClicked(MouseEvent e) {}

public void mousePressed(MouseEvent e) {}

public void mouseReleased(MouseEvent e) {}

public void mouseEntered(MouseEvent e) {}

public void mouseExited(MouseEvent e) {}

}

class MyMouseHandler extends MouseAdapter

{

public void mouseClicked(MouseEvent e) {}

} 20

Example5

Page 21: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Note: adapter pattern

• Adapter pattern is another design pattern

– We will cover this later

• It is more general than the adapter classes

discussed here

• It converts from one interface to another

• In my opinion, this isn’t exactly what these

adapters are doing – although it sort of is

• Warning: don’t confuse these adapter classes

with the adapter pattern

• Remember this warning when revising21

Page 22: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Anonymous classes

• It is really common to create a inner class which is a subclass of an adapter class, or which implements an interface, and just pass the one object into a function

– You only ever create one object of this class

– You never need to reuse the class

– So why bother giving it a name?

• You can use an anonymous class:

– Add { } and the subclass functions implementation onto the end of the new statement…

new MouseAdapter()

{

public void mouseClicked(MouseEvent e)

{ System.out.print("C"); }

});22

Example6

Page 23: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Anonymous class

• You don’t give an anonymous class a name

• You can’t give it an explicit constructor

– What would you call it anyway?

• You can give it member data (member variables)

• Member variables in Java get zeroed or null’ed

– Unlike C/C++ variables

button1.addMouseMotionListener(

new MouseMotionAdapter()

{

int count;

public void mouseDragged(MouseEvent e)

{ System.out.print("D" + (count++) ); }

} );23

Example7

Page 24: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Event Queues

• Events are handled one by one

• Something picks up your event and calls a function which asks your object to handle the event

• Not your own function calling it – your main ends…

public static void main( String[] args)

{

new Example7AnonymousClassTwoListeners().go();

new Example7AnonymousClassTwoListeners().go();

// No more ‘main()’ so main() ends now

}

• … but your program continues to execute….

• … why?

24

Page 25: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Threads

• Threads are lightweight processes

• Your process can have multiple threads running inside it

• They share the same memory (process space)

• You can create your own threads (next lecture)– There are some things that you need to be aware of

– Java provides simple fixes to avoid most problems

– You need to use the fixes though

• Swing creates its own worker thread when you display the first window– You need to understand this

– Swing is not thread-safe – only this worker thread should do any drawing – not your own code!!!

25

Page 26: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Example of main thread doing things…

• Main thread starts with

‘main()’

• When it creates the

window (setVisible())

another thread will start

• Normally main() then

ends

• Here we left main()

running…

26

createGUI()

doOther

Stuff()

Pick up

event

Handle

event

WorkerThreadTest

Page 27: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Warning

• You should not change the GUI from any thread

other than the GUI thread

• The program I just used did so though

– This is very bad

– But we got away with it because nothing else was

doing things

• Concept: thread safety

– A system is thread safe if multiple threads running at

the same time and using it cannot cause problems

– Swing is NOT threadsafe!!!27

Page 28: G51PGP Programming Paradigms - Nottinghampszja/pgp1516/g51pgp-lecture-oo8.pdf · for the program to handle – E.g. move the mouse, click on something, close a window, etc – More

Next lecture

• Threads

– InvokeLater for Swing

• Sharing data between threads

– Safely

• Monitors

• Exceptions and exception handling

28