You are on page 1of 37

JavaFX Event-driven

programming
I3305 - Chapter 2

i3305
What is event-driven programming?

i3305
What is event-driven programming?
Event object

Click Me! Handler

Event source Event handler

Represents a button click

M. El Dick 3
How to handle an event?
public void start(Stage primaryStage) {
HBox pane = new HBox(10);
pane.setAlignment(Pos.CENTER);
Button btOK = new Button("OK");
Button btCancel = new Button("Cancel");
OKHandlerClass handler1 = new OKHandlerClass(); create handler
btOK.setOnAction(handler1); register handler
CancelHandlerClass handler2 = new CancelHandlerClass();
btCancel.setOnAction(handler2);
pane.getChildren().addAll(btOK, btCancel);
Scene scene = new Scene(pane, 200,100);
primaryStage.setTitle("HandleEvent");
primaryStage.setScene(scene);
primaryStage.show();
} i3305
Event handlers
class OKHandlerClass implements EventHandler<ActionEvent> {
@Override
public void handle(ActionEvent e) { handle event
System.out.println("OK button clicked");
}
}

class CancelHandlerClass implements EventHandler<ActionEvent> {


@Override
public void handle(ActionEvent e) {
System.out.println("Cancel button clicked");
}
}

i3305
Event object hierarchy

i3305
i3305
Registering handlers

i3305
Without event handling
public void start(Stage primaryStage) {
StackPane pane = new StackPane();
Circle circle = new Circle(50);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
pane.getChildren().add(circle);
HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btEnlarge = new Button("Enlarge");
Button btShrink = new Button("Shrink");
hBox.getChildren().add(btEnlarge);
hBox.getChildren().add(btShrink);
BorderPane borderPane = new BorderPane();
borderPane.setCenter(pane);
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.CENTER);
i3305

With event handling
class CirclePane extends StackPane {
private Circle circle = new Circle(50);
public CirclePane() {
getChildren().add(circle);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
}
public void enlarge() {
circle.setRadius(circle.getRadius() + 2);
}
public void shrink() {
circle.setRadius(circle.getRadius() > 2 ?
circle.getRadius() - 2 : circle.getRadius());
}
} i3305
public class Main extends Application {
private CirclePane circlePane = new CirclePane();
public void start(Stage primaryStage) {
HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btEnlarge = new Button("Enlarge");
Button btShrink = new Button("Shrink");
hBox.getChildren().add(btEnlarge);
hBox.getChildren().add(btShrink);
btEnlarge.setOnAction(new EnlargeHandler());
btShrink.setOnAction(new ShrinkHandler());
BorderPane borderPane = new BorderPane();
borderPane.setCenter(circlePane);
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.CENTER);
Scene scene = new Scene(borderPane, 200,
i3305 150);
primaryStage.setTitle("ControlCircle");
primaryStage.setScene(scene);
primaryStage.show();
}
class ShrinkHandler implements EventHandler<ActionEvent> {
@Override public void handle(ActionEvent e) {
circlePane.shrink();
} Inner class
}
class EnlargeHandler implements EventHandler<ActionEvent> {
@Override public void handle(ActionEvent e) {
circlePane.enlarge();
}
}
public static void main(String[] args) {launch(args);}
} // End of class Main

i3305
Inner class
public class OuterClass {
private int data;
/** A method in the outer class */
public void m() { //Do something}

//An inner class


class InnerClass {
/** A method in the inner class */
public void mi() {
//Directly reference data and method defined in its outer class
data++;
m();
}
}
i3305
Anonymous inner class handlers
public void start(Stage primaryStage) { public void start(Stage primaryStage) {
// Omitted // Omitted
btEnlarge.setOnAction(new btEnlarge.setOnAction(new
EnlargeHandler()); EventHandler<ActionEvent>() {
} public void handle(ActionEvent e) {
circlePane.enlarge();
class EnlargeHandler implements }
EventHandler<ActionEvent> {
});
@Override public void
handle(ActionEvent e) { }
circlePane.enlarge();
}
}

Inner class Anonymous inner class


i3305
Anonymous handler demo
public void start(Stage primaryStage) {
hBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btNew = new Button("New");
Button btOpen = new Button("Open");
Button btSave = new Button("Save");
Button btPrint = new Button("Print");
hBox.getChildren().addAll(
btNew, btOpen, btSave, btPrint);

i3305
btNew.setOnAction(new EventHandler<ActionEvent>() {
@Override // Override the handle method
public void handle(ActionEvent e) {
System.out.println("Process New");
}
});

btOpen.setOnAction(new EventHandler<ActionEvent>() {
@Override // Override the handle method
public void handle(ActionEvent e) {
System.out.println("Process Open");
}
});

btSave.setOnAction(new EventHandler<ActionEvent>() {
@Override // Override the handle method
public void handle(ActionEvent e) {
System.out.println("Process Save");
}
});

i3305
btPrint.setOnAction(new EventHandler<ActionEvent>() {
@Override // Override the handle method
public void handle(ActionEvent e) {
System.out.println("Process Print");
}
});
Scene scene = new Scene(hBox, 300, 50);
primaryStage.setTitle("AnonymousHandlerDemo"); // Set title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}

/**
* The main method is only needed for the IDE with limited
* JavaFX support. Not needed for running from the command line.
*/
public static void main(String[] args) {
launch(args);
}
}

i3305
Lambda expression handlers
btEnlarge.setOnAction( btEnlarge.setOnAction(e -> {
new EventHandler<ActionEvent> { // Code for processing event e
@Override });
public void handle(ActionEvent e) }
{
// Code for processing event e
}
}
});

Anonymous inner class Lambda expression


i3305
Lambda handler demo
public void start(Stage primaryStage) {
hBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btNew = new Button("New");
Button btOpen = new Button("Open");
Button btSave = new Button("Save");
Button btPrint = new Button("Print");
hBox.getChildren().addAll(
btNew, btOpen, btSave, btPrint);

i3305
btNew.setOnAction(e -> System.out.println("Process New"));

btOpen.setOnAction(e -> {
System.out.println("Process Open");
});

btSave.setOnAction(e -> System.out.println("Process Save"));


btPrint.setOnAction(e -> System.out.println("Process Print"));
Scene scene = new Scene(hBox, 300, 50);
primaryStage.setTitle("AnonymousHandlerDemo"); // Set title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}

public static void main(String[] args) {


launch(args);
}
}

i3305
Mouse events
• When mouse button is:
• Pressed
• Released
• Clicked
• Moved
• Dragged on a node or a scene

i3305
constants—PRIMARY, SECONDARY, MIDDLE, and NONE—are defined in MouseButton
to indicate the left, right, middle, and none mouse buttons
i3305
Mouse event demo
public void start(Stage primaryStage) {
Pane pane = new Pane();
Text text = new Text(20, 20, "Programming is fun");
pane.getChildren().addAll(text);
text.setOnMouseDragged(e -> {
text.setX(e.getX());
text.setY(e.getY());
});
// Omitted

i3305
Key events
• When a key is:
• Pressed
• Released
• Typed on a node or a scene

i3305
keyCode is a constant, an enum type

i3305
Key code constants

i3305
Key event demo
public void start(Stage primaryStage) {
Pane pane = new Pane();
Text text = new Text(20, 20, "A");
pane.getChildren().add(text);
text.setOnKeyPressed(e -> {
switch (e.getCode()) {
case DOWN: text.setY(text.getY() + 10); break;
case UP: text.setY(text.getY() - 10); break;
case LEFT: text.setX(text.getX() - 10); break;
case RIGHT: text.setX(text.getX() + 10); break;
default:
if (Character.isLetterOrDigit(e.getText().charAt(0)))
text.setText(e.getText());
}});
Scene scene = new Scene(pane, 200,200);
text.requestFocus(); // text is focused to receive key input
i3305
Control circle with mouse and key events
class CirclePane extends StackPane {
private Circle circle = new Circle(50);
public CirclePane() {
getChildren().add(circle);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
}
public void enlarge() {
circle.setRadius(circle.getRadius() + 2);
}
public void shrink() {
circle.setRadius(circle.getRadius() > 2 ?
circle.getRadius() - 2 : circle.getRadius());
}
} i3305
public class Main extends Application {
private CirclePane circlePane = new CirclePane();

public void start(Stage primaryStage) {


HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.CENTER);
Button btEnlarge = new Button("Enlarge");
Button btShrink = new Button("Shrink");
hBox.getChildren().add(btEnlarge);
hBox.getChildren().add(btShrink);
btEnlarge.setOnAction(e -> circlePane.enlarge() );
btShrink.setOnAction(e -> circlePane.shrink() );

i3305
circlePane.setOnMouseClicked(e -> {
if (e.getButton() == MouseButton.PRIMARY) {
circlePane.enlarge();
}
else if (e.getButton() == MouseButton.SECONDARY) {
circlePane.shrink();
}
});
circlePane.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.U) {
circlePane.enlarge();
}
else if (e.getCode() == KeyCode.D) {
circlePane.shrink();
}
}); i3305
BorderPane borderPane = new BorderPane();
borderPane.setCenter(circlePane);
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.CENTER);
Scene scene = new Scene(borderPane, 200, 150);
primaryStage.setTitle("ControlCircle");
primaryStage.setScene(scene);
primaryStage.show();
circlePane.requestFocus(); Request focus on circle pane
}

public static void main(String[] args) {


launch(args);
}
} // End of class Main
i3305
Listeners for observable objects
public class Main {
public static void main(String[] args) {
DoubleProperty balance = new SimpleDoubleProperty();
balance.addListener(new InvalidationListener() {
public void invalidated(Observable ov) {
System.out.println("The new value is " +
balance.doubleValue()); balance.addListener(ov -> {
} System.out.println("The new value is " +
balance.doubleValue());});
});
balance.set(4.5);
}
} i3305
Listener for pane demo
public void start(Stage primaryStage) {
Circle circle = new Circle();
circle.setStroke(Color.BLACK); BorderPane pane = new BorderPane();
pane.setCenter(circle);
pane.widthProperty().addListener(ov ->
circle.setRadius(pane.getWidth()>pane.getHeight()?pane.getHeight()/2:
pane.getWidth()/2) );

pane.heightProperty().addListener(ov ->
circle.setRadius(pane.getWidth()>pane.getHeight()?pane.getHeight()/2:
pane.getWidth()/2) );
//omitted
i3305
Exercises

i3305
Exercise 1: Create a simple calculator

i3305
Exercise 2: Move a rectangle using mouse
• Write a program that displays a rectangle.
• You can point the mouse inside the rectangle and drag the rectangle
wherever the mouse goes. (i.e., move with mouse pressed)
• The mouse point becomes the center of the rectangle.

i3305
Exercise 3: Auto resize cylinder
• Write a program that draws a cylinder
• To set the dashed stroke for an arc:
• arc.getStrokeDashArray().addAll(6.0, 21.0);
• The cylinder’s width and height are automatically resized when the
window is resized

i3305

You might also like