[英]Invoke a ComboBox's enter key/action event handler regardless of value property change
使用可編輯的ComboBox
,有沒有辦法讓ENTER鍵事件或動作事件處理程序發生,無論Combobox
的value屬性是否已更改?
我基本上希望在按下ENTER鍵的ComboBox
的TextField
具有相同的行為,就像TextField
。
我最初的想法是簡單地使用setOnAction
作為ComboBox
; 但是,根據它的文件:
ComboBox操作,每當更改ComboBox值屬性時調用。 這可能是由於當用戶選擇彈出列表或對話框中的項目時,以編程方式更改了value屬性,或者,在可編輯的ComboBoxes的情況下,可能是用戶提供自己的輸入時(通過TextField)或其他一些輸入機制。
因此,通過使用setOnAction
,事件處理程序僅在以下情況下發生:
此外,既沒有使用setOnAction
在ComboBox
的TextField
也不使用setOnKeyPressed
實現所期望的行為。
以下是SSCCE演示:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Example extends Application {
@Override
public void start(Stage primaryStage) {
ComboBox<String> comboBox =
new ComboBox<String>(
FXCollections.observableArrayList("XYZ", "ABC"));
comboBox.setEditable(true);
comboBox.setValue(comboBox.getValue());
comboBox.setOnAction((event) -> System.out
.println("occurs on selection changes or text changes and ENTER key"));
comboBox.getEditor().setOnAction(
(event) -> System.out.println("this never happens"));
comboBox.getEditor().setOnKeyPressed((keyEvent) -> {
if (keyEvent.getCode() == KeyCode.ENTER)
System.out.println("this never happens either");
});
TextField tf = new TextField();
tf.setOnAction((event) -> System.out.println("always happens on ENTER"));
HBox hbox = new HBox(comboBox, tf);
Scene scene = new Scene(hbox);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
作為了解事件如何工作的一般方法,您總是可以使用Event.ANY添加eventfilter並查看會發生什么,例如:
comboBox.getEditor().addEventFilter(Event.ANY, e -> System.out.println(e));
事件被觸發,可以在控制台中看到。 所以你需要的是為關鍵代碼添加一個過濾器,如下所示:
comboBox.getEditor().addEventFilter(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() == KeyCode.ENTER) {
System.out.println( "Enter pressed");
}
});
關於您的問題,您可以查看ComboBoxListViewSkin,您可以在其中看到該事件已被使用。
private EventHandler<KeyEvent> textFieldKeyEventHandler = event -> {
if (textField == null || ! getSkinnable().isEditable()) return;
handleKeyEvent(event, true);
};
...
private void handleKeyEvent(KeyEvent ke, boolean doConsume) {
// When the user hits the enter or F4 keys, we respond before
// ever giving the event to the TextField.
if (ke.getCode() == KeyCode.ENTER) {
setTextFromTextFieldIntoComboBoxValue();
if (doConsume) ke.consume();
}
...
}
簡而言之:使用EventFilter而不是EventHandler。
您可以在處理JavaFX事件文檔中閱讀更多相關信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.