2017-08-24 40 views
1

我想添加到屬性偵聽器,等待這個偵聽器將被調用並刪除這個偵聽器。所以我寫了下面的代碼:如何在JavaFX中的ChangeListener中獲取對Property ChangeListener的引用?

ChangeListener<String> listener = (observable, oldValue, newValue) -> { 
     textField.setStyle("-fx-border-color:black"); 
     textField.textProperty().removeListener(listener); //LINE X 
    }; 
    textField.textProperty().addListener(listener); 

然而,在LINE X我得到Variable listener might not have been initialized。如何獲取ChangeListener中的屬性ChangeListener的引用以將其刪除?

+0

據我所知,如果你使用一個類(你只能這樣做例如匿名內部類),而不是lambda表達式。 –

回答

2

從JLS,section 15.27.2

與出現在匿名類聲明的代碼,名稱的含義,並引用聲明的可訪問性出現在拉姆達體,沿着這和超級關鍵字,是與周圍環境相同(除了lambda參數引入新名稱)。

...

實事求是地講,這是不尋常的lambda表達式需要談論本身(無論是遞歸調用自身或調用它的其他方法),而更常見的要使用名稱來引用封閉類中的東西,否則會被映射(this,toString())。 如果lambda表達式有必要引用自身(就像通過這個),應該使用方法引用或匿名內部類。

(我的重點。)

所以,簡而言之,是沒有辦法的lambda表達式來指代自己。您需要重構這是一個匿名內部類:

ChangeListener<String> listener = new ChangeListener<String>() { 
    @Override 
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) -> { 
     textField.setStyle("-fx-border-color:black"); 
     textField.textProperty().removeListener(this); 
    } 
}; 
textField.textProperty().addListener(listener); 

當然,你可能不再需要在這一點參考:

textField.textProperty().addListener(new ChangeListener<String>() { 
    @Override 
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) -> { 
     textField.setStyle("-fx-border-color:black"); 
     textField.textProperty().removeListener(this); 
    } 
}); 
相關問題