1. 引言
1.1. 概述
在这个简短教程中,我们将探讨JavaFX的Button
组件,并了解如何处理用户交互。
1.2. JavaFX API
在Java 8、9和10中,开始使用JavaFX库无需额外设置。从JDK 11开始,项目将从JDK中移除,需要在pom.xml
中添加以下依赖:
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>${javafx-maven-plugin.version}</version>
<configuration>
<mainClass>Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
2. 应用程序设置
首先,让我们创建一个小型应用程序,以便专注于事件处理器。我们从创建一个简单的FXML布局开始,其中包含一个按钮:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="com.baeldung.button.eventhandler.ButtonEventHandlerController"
prefHeight="200.0" prefWidth="300.0">
<center>
<Button fx:id="button" HBox.hgrow="ALWAYS"/>
</center>
<bottom>
<Label fx:id="label" text="Test label"/>
</bottom>
</BorderPane>
接下来,创建ButtonEventHandlerController
类。这个类负责连接UI元素和应用程序逻辑。我们在initialize
方法中设置按钮的标签:
public class ButtonEventHandlerController {
private static final Logger logger = LoggerFactory.getLogger(ButtonEventHandlerController.class);
@FXML
private Button button;
@FXML
private Label label;
@FXML
private void initialize() {
button.setText("Click me");
}
}
启动应用程序。我们应该在窗口底部看到一个名为“Click me”的按钮,以及一个测试标签:
3. 点击事件
我们从处理简单的点击事件开始,在initialize
方法中添加事件处理器:
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
logger.info("OnAction {}", event);
}
});
现在试一试。当我们点击按钮时,会看到新的日志消息:
INFO c.b.b.e.ButtonEventHandlerController - OnAction javafx.event.ActionEvent[source=Button[id=searchButton, styleClass=button]'Click me']
由于事件处理器接口只有一个方法,我们可以将其视为函数式接口,通过单个lambda表达式替换这些行,使代码更易读:
searchButton.setOnAction(event -> logger.info("OnAction {}", event));
尝试添加另一个点击事件处理器。只需复制这一行并更改日志消息,以便我们在测试应用时能看到区别:
button.setOnAction(event -> logger.info("OnAction {}", event));
button.setOnAction(event -> logger.info("OnAction2 {}", event));
现在,当点击按钮时,我们只会看到“OnAction 2”消息。这是因为第二次setOnAction
方法调用用第二个事件处理器替换了一个。
4. 不同类型的事件
我们还可以处理其他类型的事件,如鼠标按下/释放、拖动和键盘事件。
让我们为按钮添加悬停效果。当鼠标光标开始悬停在按钮上时显示阴影,鼠标离开时移除效果:
Effect shadow = new DropShadow();
searchButton.setOnMouseEntered(e -> searchButton.setEffect(shadow));
searchButton.setOnMouseExited(e -> searchButton.setEffect(null));
5. 重用事件处理器
在某些情况下,我们可能希望多次使用同一个事件处理器。让我们创建一个事件处理器,当我们在按钮上使用次要鼠标按钮点击时,增加按钮的字体大小:
EventHandler<MouseEvent> rightClickHandler = event -> {
if (MouseButton.SECONDARY.equals(event.getButton())) {
button.setFont(new Font(button.getFont().getSize() + 1));
}
};
但目前它没有功能,因为我们还没有将其与任何事件关联起来。让我们把这个事件处理器用于按钮的鼠标按下事件和标签:
button.setOnMousePressed(rightClickHandler);
label.setOnMousePressed(rightClickHandler);
现在,当我们测试应用并使用次要鼠标按钮点击标签或按钮时,会看到字体大小增加。
6. 总结
我们学习了如何为JavaFX按钮添加事件处理器,并根据事件类型执行不同的操作。
如往常一样,完整的代码实现可以在GitHub上找到。