我想在 JavaFX 中有一个可重用的按钮并为其提供一个功能。
我目前有这个:
后退按钮 Controller
public class BackButtonController {
@FXML
private Button btnBack;
private final Method method;
public BackButtonController(Method method) {
this.method = method;
}
@FXML
protected void initialize() {
this.btnBack.setOnMouseClick(() -> buttonClick());
}
public void btnClick() {
// do the received function
}
}
后退按钮.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<Button fx:id="btnBack" mnemonicParsing="false" text="Back" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
</AnchorPane>
Controller
protected void initialize() {
try {
var loader = new FXMLLoader(getClass().getResource("/views/backButton.fxml"));
loader.setController(new BackButtonController(this.test()));
this.vbPanel.getChildren().add(0, loader.load());
} catch (IOException e) {
e.printStackTrace();
}
// some other code
}
我希望能够使用发送到 Controller 的函数加载按钮,以便当按下按钮时它会运行该函数。
我一直在网上查找,但无法让它发挥作用。
我希望有人能帮助我。
最佳答案
要对按钮执行操作,您应该调用 button.setOnAction(eventHandler)
,不是button.setOnMouseClicked(mouseEventHandler)
。这样,如果按钮操作以其他方式触发而不是用鼠标单击(例如通过键盘操作或以编程方式调用 button.fire()
),所需的操作仍然会被触发。
eventHandler
已经相当于一个函数引用,它所做的只是为 handle()
提供一个方法。事件,因此,就 Java 8 而言,它形成 SAM type ,它允许使用 lambda 和方法引用的有用快捷方式。
有很多不同的方法来定义和设置事件处理程序方法。下面的源代码提供了一些示例。并非所有示例都被使用,因此它故意具有冗余代码,但它包含大量示例来演示定义和使用函数的不同方式。
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class FunctionalButton extends Application {
@Override
public void start(Stage stage) throws Exception {
Layout layout = new Layout();
layout.setFunction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println(
"Invoked function from anonymous inner class defined in " + FunctionalButton.class.getSimpleName()
);
}
});
layout.setFunction(
(actionEvent) ->
System.out.println(
"Invoked function from lambda defined in " + FunctionalButton.class.getSimpleName()
)
);
// use a method reference.
layout.setFunction(this::applicationInstanceHandleButtonAction);
stage.setScene(new Scene(layout));
stage.show();
}
private void applicationInstanceHandleButtonAction(ActionEvent event) {
System.out.println("Invoked event handler for method applicationInstanceHandleButtonAction");
}
public static void main(String[] args) {
launch(args);
}
}
class Layout extends StackPane {
private Button button = new Button("Invoke Configurable Function");
private EventHandler<ActionEvent> layOutEventHandlerWithoutLambda =
new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Invoked event handler layOutEventHandlerWithoutLambda");
}
};
private EventHandler<ActionEvent> layOutEventHandlerWithLambda =
event -> System.out.println("Invoked event handler layOutEventHandlerWithLambda");
private static void staticHandleButtonAction(ActionEvent event) {
System.out.println("Invoked event handler for method staticHandleButtonAction");
}
private void instanceHandleButtonAction(ActionEvent event) {
System.out.println("Invoked event handler for method instanceHandleButtonAction");
}
public Layout() {
getChildren().add(button);
button.setOnAction(layOutEventHandlerWithoutLambda);
button.setOnAction(layOutEventHandlerWithLambda);
button.setOnAction(Layout::staticHandleButtonAction); // Java 8 static method reference.
button.setOnAction(this::instanceHandleButtonAction); // Java 8 instance method reference.
}
public void setFunction(EventHandler<ActionEvent> eventHandler) {
button.setOnAction(eventHandler);
}
}
有关背景知识(如果您无法理解示例中的某些代码,则可以提供帮助),您可以查看:
- https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
- https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
- https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
- https://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html
当您使用 FXML 时,如果您需要知道如何将值传递给 Controller (以从 Controller 外部的另一个类设置按钮上的事件处理程序),请查看:
关于java - 创建一个带有函数参数的可重用按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59196386/