如何重置ComboBox并显示PromptText?

Zep*_*hyr 3 java combobox javafx

注意:我 在这里扩展重复的问题,因为它不包括 MCVE。我发现的其他几个类似问题也不包括有效的答案。

我无法找到清除选择后ComboBox显示的方法。PromptText

这是 MCVE:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        final VBox root = new VBox(10);
        root.setAlignment(Pos.TOP_CENTER);
        root.setPadding(new Insets(10));

        final ComboBox<String> cboSelection = new ComboBox<>();
        final Button btnClear = new Button("Clear");

        // Set ComboBox selections
        final ObservableList<String> subjectsList = FXCollections.observableArrayList();
        subjectsList.addAll("Software", "Math", "Physics");

        // Setup the Subject selection
        cboSelection.setPromptText("Select Subject");
        cboSelection.setItems(subjectsList);

        // Set action for "Clear" button
        btnClear.setOnAction(e -> {
            cboSelection.setValue(null);
        });

        root.getChildren().addAll(cboSelection, btnClear);

        primaryStage.setTitle("ComboBox Demo");
        primaryStage.setScene(new Scene(root, 200, 100));
        primaryStage.show();


    }


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

}
Run Code Online (Sandbox Code Playgroud)

单击“清除”按钮会将所选值设置为null并清除 的选择ComboBox,但不再显示提示文字。这看起来不像正常的预期行为。

我努力了clearSelection()setPromptText()按钮内onAction进行操作,但似乎没有任何效果可以恢复提示文本。

Jam*_*s_D 6

根据文档,提示文本实际上根本不应该显示在此处:

提示文本并非在所有情况下都显示,它依赖于 ComboBoxBase 的子类来阐明何时显示提示文本。例如,在大多数情况下,当组合框不可编辑时,永远不会显示提示文本(即,仅当允许用户通过文本输入进行输入时才显示提示文本)。

如果您想在选择为空时看到一些提示文本(并且您没有可编辑的组合框),请buttonCell在组合框上使用自定义:

    cboSelection.setPromptText("Select Subject");
    cboSelection.setButtonCell(new ListCell<String>() {
        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty) ;
            if (empty || item == null) {
                setText("Select Subject");
            } else {
                setText(item);
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

请注意,您似乎需要设置提示文本,如问题中的代码所示,以便最初显示文本。我认为这是由于相同的错误(我猜测库代码最初错误地将按钮单元格的文本设置为提示文本;如果未设置提示文本,则文本将设置为null,显然按钮单元格的更新方法被调用)。

显然,您可以通过创建以下内容的命名子类来使其可重用ListCell

public class PromptButtonCell<T> extends ListCell<T> {

    private final StringProperty promptText = new SimpleStringProperty();

    public PromptButtonCell(String promptText) {
        this.promptText.addListener((obs, oldText, newText) -> {
            if (isEmpty() || getItem() == null) {
                setText(newText);
            }
        });
        setPromptText(promptText);
    }

    public StringProperty promptTextProperty() {
        return promptText ;
    }

    public final String getPromptText() {
        return promptTextProperty().get();
    }

    public final void setPromptText(String promptText) {
        promptTextProperty().set(promptText);
    }

    @Override
    protected void updateItem(T item, boolean empty) {
        super.updateItem(item, empty);
        if (empty || item == null) {
            setText(getPromptText());
        } else {
            setText(item);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后就

cboSelection.setButtonCell("Select Subject");
cboSelection.setButtonCell(new PromptButtonCell<>("Select Subject"));
Run Code Online (Sandbox Code Playgroud)