SECTION 2: ETHICS - Absolute Quality - Absolute Results

49
Chapter 15 Event-Driven Programming and Animations 1

Transcript of SECTION 2: ETHICS - Absolute Quality - Absolute Results

Page 1: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Chapter 15

Event-Driven Programming and Animations

1

Page 2: SECTION 2: ETHICS - Absolute Quality - Absolute Results

GUIs are event driven

2

In console applications the program is in charge of the flow of control, but in a GUI application it is the user that dictates what happens next.

Execution flow is all depended on what action the user takes. These actions are manifested as Events, which the application then handles.

Page 3: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Event Handling

3

Source Object

(Button)

Event Object

Target Object

(Event

Handler)

must implement: EventHandler<T extends Event>must register with source: source.setOnAction(handler)

Page 4: SECTION 2: ETHICS - Absolute Quality - Absolute Results

External Handler

4

Class

Handler

Page 5: SECTION 2: ETHICS - Absolute Quality - Absolute Results

5

public class Main extends Application {

@Override public void start(Stage primaryStage) { okButton.setOnAction( new OkHandlerClass() ); } }

class OkHandlerClass implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent e) {...} }

Page 6: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Inner Handler

6

Class

Handler

Page 7: SECTION 2: ETHICS - Absolute Quality - Absolute Results

7

public class Main extends Application {

@Override public void start(Stage primaryStage) { okButton.setOnAction( new OkHandlerClass() ); }

class OkHandlerClass implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent e) {...}}

}

Page 8: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Anonymous Inner Handler

8

Class

( ){ }

Page 9: SECTION 2: ETHICS - Absolute Quality - Absolute Results

9

public class Main extends Application {

@Override public void start(Stage primaryStage) {

okButton.setOnAction( new EventHandler<ActionEvent> { @Override public void handle(ActionEvent e) {...} } );

} }

Page 10: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Lambda Expression

10

Class

( ){ }

Page 11: SECTION 2: ETHICS - Absolute Quality - Absolute Results

11

public class Main extends Application {

@Override public void start(Stage primaryStage) { okButton.setOnAction( e -> {...} ); } }

Page 12: SECTION 2: ETHICS - Absolute Quality - Absolute Results

The Event class hierarchy

12

EventObject

Event

InputEventActionEvent WindowEvent

KeyEventMouseEvent

java.util.

javafx.event.

This is a sample of the event types.

The widget (source object) the user interacts with on a UI fires an Event object indicating to the application what has happened. In the application a Listener object receives this Event and handles it accordingly.

The OS is the dispatcher of such events, meaning it detects the user's action and sends the Event to the application.

Your code ties the source object to the listener object by registering the listener with the source object. This registration is a form of delegation. The source object delegates to the listener object the task of handling the event.

Page 13: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Events by action

13

Source Object Event

Button, TextField, RadioButton, CheckBox, ComboBox ActionEvent

Node, Scene MouseEvent or KeyEvent

Page 14: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Event Registration

14

Source Object

Event Handler Object

.setOnAction ( )

.setOnMouseXXX( )

.setOnKeyXXX ( )

Page 15: SECTION 2: ETHICS - Absolute Quality - Absolute Results

A source object raises the event

15

Source Object

The user clicks on the Enlarge button, causing an ActionEvent to be raised or fired.

Page 16: SECTION 2: ETHICS - Absolute Quality - Absolute Results

16

public class Main extends Application { // create the circle pane instance private final CirclePane circlePane = new CirclePane(); @Override public void start(Stage primaryStage) { HBox sizingHB = new HBox(15.0); sizingHB.setAlignment(Pos.CENTER); Button sizeUpButton = new Button("Increase"); Button sizeDownButton = new Button("Decrease");

Page 17: SECTION 2: ETHICS - Absolute Quality - Absolute Results

17

// register the two sizing event handlers sizeUpButton.setOnAction( new SizeUpHandler()); sizeDownButton.setOnAction( new SizeDownHandler()); sizingHB.getChildren().addAll( sizeUpButton, sizeDownButton); BorderPane bp = new BorderPane(circlePane); bp.setPadding(new Insets(10, 10, 10, 10)); bp.setBottom(sizingHB); primaryStage.setTitle("Circle Size Adjustment"); primaryStage.setScene( new Scene(bp, 200, 200)); primaryStage.show(); }// end start()

Page 18: SECTION 2: ETHICS - Absolute Quality - Absolute Results

18

/* Note how these two event handler classes * are nested inside the Main class.*/ private class SizeUpHandler // inner class implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent event) { circlePane.sizeUpByOne(); } }

private class SizeDownHandler implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent event) { circlePane.sizeDownByOne(); } }}// end Main

Page 19: SECTION 2: ETHICS - Absolute Quality - Absolute Results

19

class CirclePane extends StackPane { private final Circle circle = new Circle(50, Color.YELLOW); CirclePane() { getChildren().add(circle); } public void sizeUpByOne() { circle.setRadius(circle.getRadius() + 1); } public void sizeDownByOne() { double r = circle.getRadius(); circle.setRadius(r > 5? r - 1 : r); } }

Page 20: SECTION 2: ETHICS - Absolute Quality - Absolute Results

A class may be defined inside another

20

Outer Class

Inner Class

Inner classes are intimately related to the classes they reside within.

Think of it this way: The inner class exists only for the purpose of serving the outer class. It is not useful to any other class on its own.

Inner classes are good canditates for listeners for this exact reason.

Page 21: SECTION 2: ETHICS - Absolute Quality - Absolute Results

It is compiled into OuterClass$InnerClass.class

21

Page 22: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Can access outer class's members

22

The inner class can access directly the ivars and methods of its outer class. This includes private and public alike.

The outer class however must abide by the encapsulation rules. In other words, it can only access the public interface of the inner class.

Page 23: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Can have any access modifier (public, protected, default, private)

23

This of course will dictate how a client of the outer class will be able to access the inner class.

Page 24: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Can be defined as static

24

If the inner class is static then its accessed by using the outer class's name, like usual.

Page 25: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Create inner class object

25

OuterClass.InnerClass innerObject

= outerObject.new InnerClass();

This is permitted only if inner class's access modifier allows this. For example, it must not be private nor static.

Page 26: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Create Static inner class object

26

OuterClass.InnerClass innerObject

= new OuterClass. InnerClass();

This is permitted only if inner class's access modifier allows this. For example, it must not be private nor static.

Page 27: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Make inner into anonymous inner

27

sizeUpButton.setOnAction(new SizeUpHandler()); ... private class SizeUpHandler implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent event) { circlePane.sizeUpByOne(); } }

Anonymous inner classes can replace the 1:1 delegation model, since it saves you the trouble of first defining the named class and then registering an instance of it with the source object.

On the other hand, with a 1:n relationship, this will lead to a lot more code and duplicated effort. In this case you are probably better off sticking with the named class and registering it will all the widgets.

Page 28: SECTION 2: ETHICS - Absolute Quality - Absolute Results

28

sizeUpButton.setOnAction( new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { circlePane.sizeUpByOne(); } });

Anonymous inner classes can replace the 1:1 delegation model, since it saves you the trouble of first defining the named class and then registering an instance of it with the source object.

On the other hand, with a 1:n relationship, this will lead to a lot more code and duplicated effort. In this case you are probably better off sticking with the named class and registering it will all the widgets.

Page 29: SECTION 2: ETHICS - Absolute Quality - Absolute Results

An anonymous inner class must extend a superclass ...

29

... but never list extends

Page 30: SECTION 2: ETHICS - Absolute Quality - Absolute Results

... or implement an interface

30

... but never list implements

Page 31: SECTION 2: ETHICS - Absolute Quality - Absolute Results

It must implement all methods in superclass or interface

31

Page 32: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Always uses super's no-arg constructor

32

Page 33: SECTION 2: ETHICS - Absolute Quality - Absolute Results

It is compiled intoOuterClass$n.class

33

Where # starts out with 1 and increases by 1 for each anonymous class.

Page 34: SECTION 2: ETHICS - Absolute Quality - Absolute Results

lambas: slice bread?

34

/* anonymous handler */ sizeUpButton.setOnAction( new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { circlePane.sizeUpByOne(); } });

/* lamba expression */ sizeUpButton.setOnAction(e -> { circlePane.sizeUpByOne(); });

Anonymous inner classes can replace the 1:1 delegation model, since it saves you the trouble of first defining the named class and then registering an instance of it with the source object.

On the other hand, with a 1:n relationship, this will lead to a lot more code and duplicated effort. In this case you are probably better off sticking with the named class and registering it will all the widgets.

Page 35: SECTION 2: ETHICS - Absolute Quality - Absolute Results

(type p1, type p2,...) -> statement

35

Page 36: SECTION 2: ETHICS - Absolute Quality - Absolute Results

(type p1, ...) -> { statements; }

36

Page 37: SECTION 2: ETHICS - Absolute Quality - Absolute Results

(p1, ...) -> { statements; }

37

type inferred

Page 38: SECTION 2: ETHICS - Absolute Quality - Absolute Results

p -> { statements; }

38

single parameter

Page 39: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Mouse Events

39

.setOnMousePressed()

.setOnMouseReleased()

.setOnMouseClicked()

.setOnMouseEntered()

.setOnMouseExited()

.setOnMouseMoved()

.setOnMouseDragged()

Page 40: SECTION 2: ETHICS - Absolute Quality - Absolute Results

40

Text text = new Text(20, 20, "Programming is fun");

text.setOnMouseDragged(e -> { text.setX( e.getX() ); text.setY( e.getY() ); });

Page 41: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Key Events

41

.setOnKeyPressed()

.setOnKeyReleased()

.setOnKeyTyped()

Page 42: SECTION 2: ETHICS - Absolute Quality - Absolute Results

42

private final CirclePane circlePane = new CirclePane();

/* control must have focus for KeyEvent */ circlePane.requestFocus();

circlePane.setOnKeyPressed( e -> { if (e.getCode() == KeyCode.I) { circlePane.sizeUpBy(RADIUS_INCREMENT); } else if (e.getCode() == KeyCode.D) { circlePane.sizeDownBy(RADIUS_INCREMENT); } });

Page 43: SECTION 2: ETHICS - Absolute Quality - Absolute Results

Animation

43

Animation

FadeTransitionPathTransition Timeline

Page 44: SECTION 2: ETHICS - Absolute Quality - Absolute Results

44

Animation

-autoReverse: BooleanProperty -cycleCount: IntegerProperty -rate: DoubleProperty -status: ReadOnlyObjectProperty<Animation.Status>

+pause(): void +play(): void +stop(): void

Page 45: SECTION 2: ETHICS - Absolute Quality - Absolute Results

45

PathTransition-duration: ObjectProperty<Duration> -node: ObjectProperty<Node> -orientation: ObjectProperty <PathTransition.OrientationType> -path: ObjectType<Shape>

+PathTransition() +PathTransition(duration: Duration, path: Shape) +PathTransition(duration: Duration, path: Shape, node: Node)

Page 46: SECTION 2: ETHICS - Absolute Quality - Absolute Results

46

Circle circlePath = new Circle(100, 100, 50); Circle orbitingDot = new Circle(100, 50, 5);

// Create the path transition PathTransition pt = new PathTransition( Duration.millis(4000), circlePath, orbitingDot);

pt.setInterpolator(Interpolator.LINEAR); pt.setOrientation( PathTransition.OrientationType.NONE); pt.setCycleCount(Timeline.INDEFINITE); pt.setAutoReverse(false);

pt.play();

Page 47: SECTION 2: ETHICS - Absolute Quality - Absolute Results

47

FadeTransition-duration: ObjectProperty<Duration> -node: ObjectProperty<Node> -fromValue: DoubleProperty -toValue: DoubleProperty -byValue: DoubleProperty

+FadeTransition() +FadeTransition(duration: Duration) +PathTransition(duration: Duration, node: Node)

Page 48: SECTION 2: ETHICS - Absolute Quality - Absolute Results

48

Timeline

+Timeline() +Timeline(double targetFramerate) +Timeline(double targetFramerate, KeyFrame...keyFrames) +Timeline(KeyFrame...keyFrames)

Page 49: SECTION 2: ETHICS - Absolute Quality - Absolute Results

49

Text text = new Text(20, 50, "Programming is fun");

Timeline animation = new Timeline( new KeyFrame(Duration.millis(500), e -> { if (text.getText().length() != 0) { text.setText(""); } else { text.setText("Programming is fun"); } }) );