- GUI
- Windows API tutorial
- Introduction to Windows API
- Windows API main functions
- System functions in Windows API
- Strings in Windows API
- Date & time in Windows API
- A window in Windows API
- First steps in UI
- Windows API menus
- Windows API dialogs
- Windows API controls I
- Windows API controls II
- Windows API controls III
- Advanced controls in Windows API
- Custom controls in Windows API
- The GDI in Windows API
- PyQt4 tutorial
- PyQt5 tutorial
- Qt4 tutorial
- Introduction to Qt4 toolkit
- Qt4 utility classes
- Strings in Qt4
- Date and time in Qt4
- Working with files and directories in Qt4
- First programs in Qt4
- Menus and toolbars in Qt4
- Layout management in Qt4
- Events and signals in Qt4
- Qt4 Widgets
- Qt4 Widgets II
- Painting in Qt4
- Custom widget in Qt4
- The Breakout game in Qt4
- Qt5 tutorial
- Introduction to Qt5 toolkit
- Strings in Qt5
- Date and time in Qt5
- Containers in Qt5
- Working with files and directories in Qt5
- First programs in Qt5
- Menus and toolbars in Qt5
- Layout management in Qt5
- Events and signals in Qt5
- Qt5 Widgets
- Qt5 Widgets II
- Painting in Qt5
- Custom widget in Qt5
- Snake in Qt5
- The Breakout game in Qt5
- PySide tutorial
- Tkinter tutorial
- Tcl/Tk tutorial
- Qt Quick tutorial
- Java Swing tutorial
- JavaFX tutorial
- Java SWT tutorial
- wxWidgets tutorial
- Introduction to wxWidgets
- wxWidgets helper classes
- First programs in wxWidgets
- Menus and toolbars in wxWidgets
- Layout management in wxWidgets
- Events in wxWidgets
- Dialogs in wxWidgets
- wxWidgets widgets
- wxWidgets widgets II
- Drag and Drop in wxWidgets
- Device Contexts in wxWidgets
- Custom widgets in wxWidgets
- The Tetris game in wxWidgets
- wxPython tutorial
- Introduction to wxPython
- First Steps
- Menus and toolbars
- Layout management in wxPython
- Events in wxPython
- wxPython dialogs
- Widgets
- Advanced widgets in wxPython
- Drag and drop in wxPython
- Internationalisation
- Application skeletons in wxPython
- The GDI
- Mapping modes
- Creating custom widgets
- Tips and Tricks
- wxPython Gripts
- The Tetris game in wxPython
- C# Winforms Mono tutorial
- Java Gnome tutorial
- Introduction to Java Gnome
- First steps in Java Gnome
- Layout management in Java Gnome
- Layout management II in Java Gnome
- Menus in Java Gnome
- Toolbars in Java Gnome
- Events in Java Gnome
- Widgets in Java Gnome
- Widgets II in Java Gnome
- Advanced widgets in Java Gnome
- Dialogs in Java Gnome
- Pango in Java Gnome
- Drawing with Cairo in Java Gnome
- Drawing with Cairo II
- Nibbles in Java Gnome
- QtJambi tutorial
- GTK+ tutorial
- Ruby GTK tutorial
- GTK# tutorial
- Visual Basic GTK# tutorial
- PyGTK tutorial
- Introduction to PyGTK
- First steps in PyGTK
- Layout management in PyGTK
- Menus in PyGTK
- Toolbars in PyGTK
- Signals & events in PyGTK
- Widgets in PyGTK
- Widgets II in PyGTK
- Advanced widgets in PyGTK
- Dialogs in PyGTK
- Pango
- Pango II
- Drawing with Cairo in PyGTK
- Drawing with Cairo II
- Snake game in PyGTK
- Custom widget in PyGTK
- PHP GTK tutorial
- C# Qyoto tutorial
- Ruby Qt tutorial
- Visual Basic Qyoto tutorial
- Mono IronPython Winforms tutorial
- Introduction
- First steps in IronPython Mono Winforms
- Layout management
- Menus and toolbars
- Basic Controls in Mono Winforms
- Basic Controls II in Mono Winforms
- Advanced Controls in Mono Winforms
- Dialogs
- Drag & drop in Mono Winforms
- Painting
- Painting II in IronPython Mono Winforms
- Snake in IronPython Mono Winforms
- The Tetris game in IronPython Mono Winforms
- FreeBASIC GTK tutorial
- Jython Swing tutorial
- JRuby Swing tutorial
- Visual Basic Winforms tutorial
- JavaScript GTK tutorial
- Ruby HTTPClient tutorial
- Ruby Faraday tutorial
- Ruby Net::HTTP tutorial
- Java 2D games tutorial
- Java 2D tutorial
- Cairo graphics tutorial
- PyCairo tutorial
- HTML5 canvas tutorial
- Python tutorial
- Python language
- Interactive Python
- Python lexical structure
- Python data types
- Strings in Python
- Python lists
- Python dictionaries
- Python operators
- Keywords in Python
- Functions in Python
- Files in Python
- Object-oriented programming in Python
- Modules
- Packages in Python
- Exceptions in Python
- Iterators and Generators
- Introspection in Python
- Ruby tutorial
- PHP tutorial
- Visual Basic tutorial
- Visual Basic
- Visual Basic lexical structure
- Basics
- Visual Basic data types
- Strings in Visual Basic
- Operators
- Flow control
- Visual Basic arrays
- Procedures & functions in Visual Basic
- Organizing code in Visual Basic
- Object-oriented programming
- Object-oriented programming II in Visual Basic
- Collections in Visual Basic
- Input & output
- Tcl tutorial
- C# tutorial
- Java tutorial
- AWK tutorial
- Jetty tutorial
- Tomcat Derby tutorial
- Jtwig tutorial
- Android tutorial
- Introduction to Android development
- First Android application
- Android Button widgets
- Android Intents
- Layout management in Android
- Android Spinner widget
- SeekBar widget
- Android ProgressBar widget
- Android ListView widget
- Android Pickers
- Android menus
- Dialogs
- Drawing in Android
- Java EE 5 tutorials
- Introduction
- Installing Java
- Installing NetBeans 6
- Java Application Servers
- Resin CGIServlet
- JavaServer Pages, (JSPs)
- Implicit objects in JSPs
- Shopping cart
- JSP & MySQL Database
- Java Servlets
- Sending email in a Servlet
- Creating a captcha in a Servlet
- DataSource & DriverManager
- Java Beans
- Custom JSP tags
- Object relational mapping with iBATIS
- Jsoup tutorial
- MySQL tutorial
- MySQL quick tutorial
- MySQL storage engines
- MySQL data types
- Creating, altering and dropping tables in MySQL
- MySQL expressions
- Inserting, updating, and deleting data in MySQL
- The SELECT statement in MySQL
- MySQL subqueries
- MySQL constraints
- Exporting and importing data in MySQL
- Joining tables in MySQL
- MySQL functions
- Views in MySQL
- Transactions in MySQL
- MySQL stored routines
- MySQL Python tutorial
- MySQL Perl tutorial
- MySQL C API programming tutorial
- MySQL Visual Basic tutorial
- MySQL PHP tutorial
- MySQL Java tutorial
- MySQL Ruby tutorial
- MySQL C# tutorial
- SQLite tutorial
- SQLite C tutorial
- SQLite PHP tutorial
- SQLite Python tutorial
- SQLite Perl tutorial
- SQLite Ruby tutorial
- SQLite C# tutorial
- SQLite Visual Basic tutorial
- PostgreSQL C tutorial
- PostgreSQL Python tutorial
- PostgreSQL Ruby tutorial
- PostgreSQL PHP tutorial
- PostgreSQL Java tutorial
- Apache Derby tutorial
- SQLAlchemy tutorial
- MongoDB PHP tutorial
- MongoDB Java tutorial
- MongoDB JavaScript tutorial
- MongoDB Ruby tutorial
- Spring JdbcTemplate tutorial
- JDBI tutorial
JavaFX events
GUI applications are event-driven. An application reacts to different event types which are generated during its lifetime. Events are generated by a user (a mouse click), an application (a timer), or the system (a clock).
An event is a notification about a change. It encapsulates the state changes in the event source. Registered event filters and event handlers within the application receive the event and provide a response.
Every event in JavaFX has three properties:
- Event source
- Event target
- Event type
Event source is the object whose state changes; it generates events. Event target is the destination of the an event. Event type provides additional classification to events of the same Event
class.
Event source object delegates the task of handling an event to the event handler. When the event occurs, the event source creates an event object and sends it to each registered handler.
Event handler
EventHandler
handles events of a specific class or type. The event handler is set to the event source. It has a handle()
method, where we put the code that is invoked in reaction to the generated event.
EventHandlerEx.java
package com.zetcode; import javafx.application.Application; import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program uses two EventHandlers for * two different Events. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class EventHandlerEx extends Application { @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { HBox root = new HBox(); ContextMenu conMenu = new ContextMenu(); MenuItem noopMi = new MenuItem("No op"); MenuItem exitMi = new MenuItem("Exit"); conMenu.getItems().addAll(noopMi, exitMi); exitMi.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { Platform.exit(); } }); root.setOnMousePressed(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (event.isSecondaryButtonDown()) { conMenu.show(root, event.getScreenX(), event.getScreenY()); } } }); Scene scene = new Scene(root, 300, 250); stage.setTitle("EventHandler"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
The example uses two EventHandlers
for two different Events
.
ContextMenu conMenu = new ContextMenu();
ContextMenu
is a popup control containing an list of menu items.
MenuItem noop = new MenuItem("No op"); MenuItem exit = new MenuItem("Exit"); conMenu.getItems().addAll(noop, exit);
Two MenuItems
are created and added to the context menu.
exitMi.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { Platform.exit(); } });
With the setOnAction()
method, we set an event handler for an ActionEvent
. The EventHandler's
handle()
method exits the application with the Platform.exit()
method.
root.setOnMousePressed(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (event.isSecondaryButtonDown()) { conMenu.show(root, event.getScreenX(), event.getScreenY()); } } });
With the setOnMousePressed()
method, we set an event handler for a MouseEvent
. When we click the secondary mouse button (usually the right one), the context menu is shown on the screen; it is displayed below the x and y coordinates of the mouse click.
Event properties
The following program explores the properties of a MouseEvent
. It is an event that occurs due to the user interacting with a mouse.
EventSourceEx.java
package com.zetcode; import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Pane; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program explores the properties of * an event. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class EventSourceEx extends Application { @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { Pane root = new Pane(); Rectangle rect = new Rectangle(30, 30, 80, 80); rect.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent e) { System.out.println(e.getSource()); System.out.println(e.getTarget()); System.out.println(e.getEventType()); System.out.format("x:%f, y:%f%n", e.getSceneX(), e.getSceneY()); System.out.format("x:%f, y:%f%n", e.getScreenX(), e.getScreenY()); } }); root.getChildren().addAll(rect); Scene scene = new Scene(root, 300, 250); stage.setTitle("Event properties"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
In the example, we have a rectangle shape. We add an event handler to the mouse clicked event type.
rect.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent e) { ... } });
The setOnMouseClicked()
adds an event handler to the mouse clicked event types. The handler is an anonymous inner class. Its handle()
method is invoked when a mouse click is detected on the rectangle.
System.out.println(e.getSource()); System.out.println(e.getTarget()); System.out.println(e.getEventType());
These three are the generic properties, available for all events. The getSource()
method returns an object on which the event initially occurred. The getTarget()
method returns the event target of this event. In our case, the event source and the event target is the same—the rectangle. The getEventType()
method returns the event type of the MouseEvent
. In our case it returns the MOUSE_CLICKED
value.
System.out.format("x:%f, y:%f%n", e.getSceneX(), e.getSceneY()); System.out.format("x:%f, y:%f%n", e.getScreenX(), e.getScreenY());
These four properties are specific to this event. We print the x and y coordinates of a mouse click, relative to the scene and to the screen.
Lambda expression
Since JDK 8, it is possible to replace an anonymous inner class with a lambda expression.
rect.setOnMouseClicked((MouseEvent e) -> { System.out.println(e.getSource()); System.out.println(e.getTarget()); System.out.println(e.getEventType()); System.out.format("x:%f, y:%f%n", e.getSceneX(), e.getSceneY()); System.out.format("x:%f, y:%f%n", e.getScreenX(), e.getScreenY()); });
This is the event handlig code from the previous example rewritten using the lambda expression.
Generic handler
In the next example, we create a generic event handler that listens for all kinds of events.
GenericHandlerEx.java
package com.zetcode; import javafx.application.Application; import javafx.event.Event; import javafx.event.EventHandler; import javafx.event.EventType; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.StackPane; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program adds a generic event * handler to a button control. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class GenericHandlerEx extends Application { @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { StackPane root = new StackPane(); Button btn = new Button("Button"); btn.addEventHandler(EventType.ROOT, new GenericHandler()); root.getChildren().add(btn); Scene scene = new Scene(root, 300, 250); stage.setTitle("Generic handler"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } private class GenericHandler implements EventHandler<Event> { @Override public void handle(Event event) { System.out.println(event.getEventType()); } } }
This example has one button control. A generic handler is plugged to the button.
Button btn = new Button("Button"); btn.addEventHandler(EventType.ROOT, new GenericHandler());
The addEventHandler()
method registers an event handler to the button node for the specified event type. The EventType.ROOT
stands for all event types.
private class GenericHandler implements EventHandler<Event> { @Override public void handle(Event event) { System.out.println(event.getEventType()); } }
The handler prints the event type to the console in its handle()
method.
Multiple sources
It is possible to add a single event handler to multiple sources. The source of the event can be determined with the getSource()
method.
MultipleSourcesEx.java
package com.zetcode; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program plugs an EventHandler to multiple * controls. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class MultipleSourcesEx extends Application { private Label lbl; @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { AnchorPane root = new AnchorPane(); VBox vbox = new VBox(5); Button btn1 = new Button("Close"); Button btn2 = new Button("Open"); Button btn3 = new Button("Find"); Button btn4 = new Button("Save"); MyButtonHandler mbh = new MyButtonHandler(); btn1.setOnAction(mbh); btn2.setOnAction(mbh); btn3.setOnAction(mbh); btn4.setOnAction(mbh); vbox.getChildren().addAll(btn1, btn2, btn3, btn4); lbl = new Label("Ready"); AnchorPane.setTopAnchor(vbox, 10d); AnchorPane.setLeftAnchor(vbox, 10d); AnchorPane.setBottomAnchor(lbl, 10d); AnchorPane.setLeftAnchor(lbl, 10d); root.getChildren().addAll(vbox, lbl); Scene scene = new Scene(root, 350, 200); stage.setTitle("Multiple sources"); stage.setScene(scene); stage.show(); } private class MyButtonHandler implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent event) { Button btn = (Button) event.getSource(); lbl.setText(String.format("Button %s fired", btn.getText())); } } public static void main(String[] args) { launch(args); } }
The example has four buttons and a label. One event handler is added to all four buttons. The name of the fired button is displayed in the label.
Button btn1 = new Button("Close"); Button btn2 = new Button("Open"); Button btn3 = new Button("Find"); Button btn4 = new Button("Save");
These four buttons will share a single event handler.
MyButtonHandler mbh = new MyButtonHandler();
An instance of a MyButtonHandler
is created. It is implemented as a inner named class.
btn1.setOnAction(mbh); btn2.setOnAction(mbh); btn3.setOnAction(mbh); btn4.setOnAction(mbh);
The handler is added to four different buttons with the setOnAction()
method.
private class MyButtonHandler implements EventHandler<ActionEvent> { @Override public void handle(ActionEvent event) { Button btn = (Button) event.getSource(); lbl.setText(String.format("Button %s fired", btn.getText())); } }
Inside the handle()
method of the MyButtonHandler
, we determine the source of the event and build a message using the source's text label. The message is set to the label control with its setText()
method.

The java.util.Timer
The java.util.Timer
schedules tasks for future execution in a background thread. TimerTask
is a task that can be scheduled for one-time or repeated execution by a timer.
TimerEx.java
package com.zetcode; import java.util.Timer; import java.util.TimerTask; import javafx.application.Application; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.Spinner; import javafx.scene.layout.HBox; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program uses a java.util.Timer to * schedule a task. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class TimerEx extends Application { int delay = 0; @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { HBox root = new HBox(10); root.setPadding(new Insets(10)); Timer timer = new java.util.Timer(); Spinner spinner = new Spinner(1, 60, 5); spinner.setPrefWidth(80); Button btn = new Button("Show message"); btn.setOnAction(event -> { delay = (int) spinner.getValue(); timer.schedule(new MyTimerTask(), delay*1000); }); root.getChildren().addAll(btn, spinner); stage.setOnCloseRequest(event -> { timer.cancel(); }); Scene scene = new Scene(root); stage.setTitle("Timer"); stage.setScene(scene); stage.show(); } private class MyTimerTask extends TimerTask { @Override public void run() { Platform.runLater(() -> { Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("Information dialog"); alert.setHeaderText("Time elapsed information"); String contxt; if (delay == 1) { contxt = "1 second has elapsed"; } else { contxt = String.format("%d seconds have elapsed", delay); } alert.setContentText(contxt); alert.showAndWait(); }); } } public static void main(String[] args) { launch(args); } }
The example has two controls: a button and a spinner. The button starts a timer, which shows a message dialog after a delay. The delay is chosen by the spinner control.
Timer timer = new java.util.Timer();
An instance of the java.util.Timer
is created.
Spinner spinner = new Spinner(1, 60, 5);
The Spinner
control is used to choose the amount of the delay. Its parameters are the minimum, maximum, and current values. The values are in milliseconds.
btn.setOnAction(event -> { delay = (int) spinner.getValue(); timer.schedule(new MyTimerTask(), delay*1000); });
In the button's event handler, we get the spinner's current value with the getValue()
method and schedule the task with the timer's schedule()
method.
stage.setOnCloseRequest(event -> { timer.cancel(); });
We cancel the timer when the application is terminated with the timer's cancel()
method.
private class MyTimerTask extends TimerTask { @Override public void run() { Platform.runLater(() -> { Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("Information dialog"); alert.setHeaderText("Time elapsed information"); String contxt; if (delay == 1) { contxt = "1 second has elapsed"; } else { contxt = String.format("%d seconds have elapsed", delay); } alert.setContentText(contxt); alert.showAndWait(); }); } }
The runLater()
method executes the task on the JavaFX Application Thread. We show a message dialog informing about the elapsed time.

Moving a window
The following example shows the position of the application window on the screen.
MovingWindowEx.java
package com.zetcode; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.VBox; import javafx.stage.Stage; /** * ZetCode JavaFX tutorial * * This program shows the screen coordinates * of the application window in two labels. * * Author: Jan Bodnar * Website: zetcode.com * Last modified: June 2015 */ public class MovingWindowEx extends Application { int x = 0; int y = 0; Label lblx; Label lbly; @Override public void start(Stage stage) { initUI(stage); } private void initUI(Stage stage) { VBox root = new VBox(10); root.setPadding(new Insets(10)); String txt1 = String.format("x: %d", x); lblx = new Label(txt1); String txt2 = String.format("y: %d", y); lbly = new Label(txt2); root.getChildren().addAll(lblx, lbly); stage.xProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { doChange(newValue); } private void doChange(Number newValue) { x = newValue.intValue(); updateXLabel(); } }); stage.yProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { doChange(newValue); } private void doChange(Number newValue) { y = newValue.intValue(); updateYLabel(); } }); Scene scene = new Scene(root, 300, 250); stage.setTitle("Moving window"); stage.setScene(scene); stage.show(); } private void updateXLabel() { String txt = String.format("x: %d", x); lblx.setText(txt); } private void updateYLabel() { String txt = String.format("y: %d", y); lbly.setText(txt); } public static void main(String[] args) { launch(args); } }
The example shows the current window coordinates in two label controls. To get the window position, we listen for changes of the xProperty
and yProperty
of the stage.
String txt1 = String.format("x: %d", x); lblx = new Label(txt1); String txt2 = String.format("y: %d", y); lbly = new Label(txt2);
These two labels show the x and y coordinates of the top-left corner of the application window.
stage.xProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { doChange(newValue); } private void doChange(Number newValue) { x = newValue.intValue(); updateXLabel(); } });
The xProperty
stores the horizontal location of the stage on the screen. We add a ChangeListener
to listen for changes of the property. Each time the property is modified, we retrieve the new value and update the label.

This part of the JavaFX tutorial was dedicated to JavaFX events.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论