2016-06-08 81 views
2

理論上這種方法引用應該可以工作,但它不會。我究竟做錯了什麼?JavaFX方法參考事件處理

如果我替換lambda表達式的方法參考但它確實工作:

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); 

所以作爲lambda表達式或方法引用傳遞的方法應該採取ActionEvent類型的單個參數,並且具有void返回類型。

btnPush方法不帶任何參數,因此它不匹配。

(另一種方式來看待這個,也許,是this::btnPush相當於lambda表達式() -> this.btnPush(),而lambda表達式不會是setOnAction有效的論述,無論是。)

所以,你既可以使用lambda表達式爲您呈現,也可以修改該方法確定指標:

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

現在您的lambda表達式的版本將

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

這正是針對其方法參考被設計方案:

btn.setOnAction(this::btnPush); 

(你可以,當然,替換的ActionEvent任何超類方法的參數類型,例如EventObject,它仍然可以通過簡單的上傳規則來工作。但是你必須有一個參數,可以指定一個ActionEvent的參考。)

+0

謝謝,這很清楚! The()當然是一個錯誤,在測試Lambda後忘記刪除它們。 – WestMD

+0

我假設'()'是一個錯字,但想要完成。請不要忘記標記答案是正確的;它會幫助其他人在搜索中找到它。 –