java - 创建一个带有函数参数的可重用按钮

标签 java javafx

我想在 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);
    }
}

有关背景知识(如果您无法理解示例中的某些代码,则可以提供帮助),您可以查看:

当您使用 FXML 时,如果您需要知道如何将值传递给 Controller ​​(以从 Controller 外部的另一个类设置按钮上的事件处理程序),请查看:

关于java - 创建一个带有函数参数的可重用按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59196386/

相关文章:

java - 如何在 Java 中操纵窗口文件夹结构?

java - 使用 volatile 变量停止线程

java - JMS,检测临时队列何时被破坏

java - Android View 枚举

java - TreeTableView CheckBoxTreeTableCell 中的 ChangeListener 每次点击都会触发多次

css - JavaFX CSS 不工作

button - 使用 JavaFX 2.2 助记符(和加速器)

java - 通过比较行排序

使用 Java 9 和 Intellij Idea 不存在 JavaFX

JavaFX 8 : How to remove the last white pixel from the combobox list