簡體   English   中英

無論值屬性更改如何,都調用ComboBox的enter鍵/操作事件處理程序

[英]Invoke a ComboBox's enter key/action event handler regardless of value property change

使用可編輯的ComboBox ,有沒有辦法讓ENTER鍵事件或動作事件處理程序發生,無論Combobox的value屬性是否已更改?

我基本上希望在按下ENTER鍵的ComboBoxTextField具有相同的行為,就像TextField

我曾經嘗試過什么

我最初的想法是簡單地使用setOnAction作為ComboBox ; 但是,根據它的文件:

ComboBox操作,每當更改ComboBox值屬性時調用。 這可能是由於當用戶選擇彈出列表或對話框中的項目時,以編程方式更改了value屬性,或者,在可編輯的ComboBoxes的情況下,可能是用戶提供自己的輸入時(通過TextField)或其他一些輸入機制。

因此,通過使用setOnAction ,事件處理程序僅在以下情況下發生:

  1. 通過從下拉OR中選擇更改來更改value屬性
  2. value屬性通過用戶輸入進行更改(即:如果用戶未鍵入任何內容並按ENTER鍵則不會發生,如果用戶在事件處理程序運行一次后沒有更改輸入並且按Enter鍵,則不會發生這種情況) 。

此外,既沒有使用setOnActionComboBoxTextField也不使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM