代码之家  ›  专栏  ›  技术社区  ›  Zephyr

如何重置组合框并显示PromptText?

  •  1
  • Zephyr  · 技术社区  · 6 年前

    注: 我在扩展重复问题 here 因为它不包括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);
        }
    
    }
    

    单击“清除”按钮将所选值设置为 null 并清除 组合框 ,但提示文本不再显示。这似乎不像正常的预期行为。

    我试过了 clearSelection() 以及 setPromptText() 在按钮内 onAction 似乎没有什么能使提示文本返回。

    1 回复  |  直到 6 年前
        1
  •  1
  •   James_D    6 年前

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

    提示文本并非在所有情况下都显示,它取决于ComboxBase的子类,以明确何时显示PromptText。例如,在大多数情况下,当组合框不可编辑时,将永远不会显示提示文本(即,只有通过文本输入允许用户输入时,才会显示提示文本)。

    如果希望在选定内容为空(并且没有可编辑的组合框)时看到一些提示文本,请使用自定义 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);
                }
            }
        });
    

    需要设置提示文本,如问题中的代码,以便使文本最初显示。我认为这是由于相同的错误(我猜测库代码最初错误地将按钮单元格的文本设置为提示文本;如果不设置提示文本,则文本设置为 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);
            }
        }
    }
    

    然后只是

    cboSelection.setButtonCell("Select Subject");
    cboSelection.setButtonCell(new PromptButtonCell<>("Select Subject"));