2016-06-08 5 views
2

Теоретически эта ссылка на метод должна работать, но это не так. Что я делаю не так?Обработка события обработки JavaFX

Она тем не менее работать, если я заменить ссылки на метод с лямбда-выражения:

btn.setOnAction (e-> btnPush());

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.Pane; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 


public class NewFXMain extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

    Button btn = new Button("Test Button"); 
    btn.setOnAction(this::btnPush()); 

    Pane root = new Pane(); 
    root.getChildren().add(btn); 

    Scene scn = new Scene(root,300,300); 

    primaryStage.setTitle("Method Reference Test"); 
    primaryStage.setScene(scn); 
    primaryStage.show(); 

    } 

    private void btnPush(){ 
     System.out.println("button pressed"); 

     } 

    public static void main(String[] args) { 
     launch(args); 
    } 

} 

ответ

3

Во-первых, ваш синтаксис неверен. Вы не можете использовать скобки на эталонный метод:

btn.setOnAction(this::btnPush); 

Во-вторых, подпись метода не соответствует подписи метода, определенного в интерфейсе. setOnAction ожидает EventHandler<ActionEvent>. Абстрактный метод определен в EventHandler<T> является

public void handle(T event); 

Таким образом, метод передается как лямбда-выражения или эталонный метод должен принимать один параметр типа ActionEvent и имеют void тип возврата.

Метод btnPush не принимает никаких параметров, поэтому он не соответствует.

(Другой способ смотреть на это, возможно, является то, что this::btnPush эквивалентно выражению лямбда () -> this.btnPush(), и что лямбда-выражение не будет действительным аргументом setOnAction либо.)

Таким образом, вы можете использовать либо лямбда-выражение, как вы показали, или вы можете изменить метод дефиницию:

private void btnPush(ActionEvent event) { 
    System.out.println("Button pressed"); 
} 

Теперь ваша лямбда-выражение версии будет

btn.setOnAction(e -> btnPush(e)); 

это именно сценарий, для которого эталонный метод предназначен:

btn.setOnAction(this::btnPush); 

(И вы можете, конечно, заменить тип параметра метода с любым суперкласс ActionEvent, такие, как Event или Object, и это все равно будет работать с помощью простых правил повышения. Но у вас должен быть параметр, которому может быть присвоена ссылка на ActionEvent.)

+0

Спасибо, это очень ясно! The() были в курсе ошибки, забыл удалить их после тестирования Lambda. – WestMD

+0

Я предполагаю, что '()' были опечатками, но хотели быть полными. Не забудьте отметить правильный ответ; это поможет другим найти его в поисках. –