Как создать лямбда выражение в своём классе?

179
27 октября 2018, 22:50

подскажите, как можно метод action() превратить в функциональное выражение. Я почитал литературу и узнал что необходимо обозначать метод аннотацией @FunctionalInterface. Но что-то не особо получается.

Вот класс:

public class ButtonRept {
    private final StackPane pane;
    private final double widthPane = 170;
    private final double heightPane = 170;
    private final double widthButton = 150;
    private final double heightButton = 150;
    public Pane getPane() {
        return pane;
    }
    private final Button button;
    public ButtonRept() {
        pane = new StackPane();
            pane.setMinSize(widthPane, heightPane);
            pane.setPrefSize(widthPane, heightPane);
            pane.setMaxSize(widthPane, heightPane);
        button = new Button();
        button.getStyleClass().add("blue-button");
        button.setOnMouseClicked(handler -> action());
        button.setMinSize(widthButton, heightButton);
        button.setPrefSize(widthButton, heightButton);
        button.setMaxSize(widthButton, heightButton);
        pane.getChildren().add(button);
    }
    public ButtonRept(String nameButton) {
        pane = new StackPane();
            pane.setMinSize(widthPane, heightPane);
            pane.setPrefSize(widthPane, heightPane);
            pane.setMaxSize(widthPane, heightPane);
        button = new Button(nameButton);
        button.getStyleClass().add("blue-button");
        button.setOnMouseClicked(handler -> action());
        button.setMinSize(widthButton, heightButton);
        button.setPrefSize(widthButton, heightButton);
        button.setMaxSize(widthButton, heightButton);
        pane.getChildren().add(button);
    }
    public void setTextAndImage(String text, Image image) {
        GridPane root = new GridPane();
            root.setMinSize(widthButton, heightButton);
            root.setPrefSize(widthButton, heightButton);
            root.setMaxSize(widthButton, heightButton);
//        root.setGridLinesVisible(true);
        double precentImage = 80.00;
        double precenText = 20.00;
        ColumnConstraints column0 = new ColumnConstraints();
        column0.setPercentWidth(100);
        root.getColumnConstraints().add(column0);
        RowConstraints row0 = new RowConstraints();
        row0.setVgrow(Priority.ALWAYS);
        RowConstraints row1 = new RowConstraints();
        row1.setPercentHeight(precenText);
        root.getRowConstraints().addAll(row0, row1);
        // Добавляем иконку
        ImageView imageView = new ImageView(image);
        double getterImageHeight = image.getHeight();
        double getterImageWidth = image.getWidth();
        double proportions = getterImageHeight/getterImageWidth;
        getterImageHeight = (heightButton/100)*precentImage;
        getterImageWidth = getterImageHeight/proportions;
        imageView.setFitHeight(getterImageHeight-5);
        imageView.setFitWidth(getterImageWidth-5);
        StackPane wrapperImage = new StackPane(imageView);
        wrapperImage.setAlignment(Pos.CENTER);
        root.add(wrapperImage, 0, 0);
        // Добавляем текст
        Label label = new Label(text);
        label.setTextAlignment(TextAlignment.CENTER);
        label.getStyleClass().add("text-rept");
        StackPane wrapperText = new StackPane(label);
        wrapperText.setAlignment(Pos.TOP_CENTER);
        root.add(wrapperText, 0, 1);
        // Устанавливаем root
        setGraphic(root);
    }
    public void setGraphic(Node node) {
        button.setGraphic(node);
    }
    public void action() {
        System.out.println("Активация кнопки...");
    }
}

Вот его реализация:

public class InnerPaneRept implements InnerPane{
    public static final String NAME_BEAN = "paneRept";
    private StackPane wrapper;
    private ScrollPane scroll;
    private TilePane pane;
    private final Image imageProducts = new Image(this.getClass().getResourceAsStream("/images/Products.png"));
    private final Image imagePrices = new Image(this.getClass().getResourceAsStream("/images/Prices.png"));
    private final Image imageBuyers = new Image(this.getClass().getResourceAsStream("/images/Buyers.png"));
    private final Image imageSells = new Image(this.getClass().getResourceAsStream("/images/Sells.png"));
    @PostConstruct
    private void init() {
        pane = new TilePane();
        pane.setAlignment(Pos.CENTER);
        ButtonRept button1 = new ButtonRept(){
            @Override
            public void action() {
                System.out.println("Активированная кнопка товаров...");
            }
        };
        button1.setTextAndImage("Товары", imageProducts);
        pane.getChildren().add(button1.getPane());
        ButtonRept button2 = new ButtonRept(){
            @Override
            public void action() {
                System.out.println("Активированная кнопка прайсов...");
            }
        };
        button2.setTextAndImage("Прайсы", imagePrices);
        pane.getChildren().add(button2.getPane());
        ButtonRept button3 = new ButtonRept(){
            @Override
            public void action() {
                System.out.println("Активированная кнопка закупок...");
            }
        };
        button3.setTextAndImage("Закупки", imageBuyers);
        pane.getChildren().add(button3.getPane());
        ButtonRept button4 = new ButtonRept(){
            @Override
            public void action() {
                System.out.println("Активированная кнопка продаж...");
            }
        };
        button4.setTextAndImage("Продажи", imageSells);
        pane.getChildren().add(button4.getPane());
        scroll = new ScrollPane(pane);
        scroll.setHbarPolicy(ScrollBarPolicy.NEVER);
        scroll.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
        wrapper = new StackPane(scroll);
        wrapper.widthProperty().addListener((observable, oldValue, newValue) -> {
            pane.setMinWidth(newValue.doubleValue());
            pane.setPrefWidth(newValue.doubleValue());
            pane.setMaxWidth(newValue.doubleValue());
        });
    }
    @Override
    public Pane getPane() {
        return wrapper;
    }
}
Answer 1

Лямбда выражение создается с помощью функционального интерфейса (интерфейса, у которого имеется всего один абстрактный метод). Вот пример:

public interface YourFunctionalInterface {
    void yourAbstractMethod();
    default void itIsPossibleToHaveDefaultMethods() {...};
    static void itIsPossibleToHaveStaticMethods() {...};
}

Использование функционального интерфейса:

void methodWhichAcceptsFuncInt(YourFunctionalInterface arg);

Теперь при вызове этого метода ему можно передать лямбда-выражение:

...
someInstance. methodWhichAcceptsFuncInt(() -> System.out.println("Hello World"));
...

Аннотация @ FunctionalInterface указывает компилятору, что это не простой интерфейс, а функциональный. И если интерфейс с данной аннотацией будет пустым или содержать больше одного абстрактного метода, будет выкинуто исключение (на этапе компиляции). Использовать аннотацию не обязательно, но это "хорошая практика".

READ ALSO
Замена только текста в HTML коде

Замена только текста в HTML коде

К примеру, есть HTML код:

215
Не работает передача параметра из url в getter. Vue js

Не работает передача параметра из url в getter. Vue js

Всем привет! Не работает передача параметра из переменной в геттер шины vue js

162
Почему не редактируется объект?

Почему не редактируется объект?

Я хочу отредактировать контакт, но после подтверждения, получаю ошибку:

180