Reputation: 10253
Note: I am expanding on duplicate question here because it does not include a MCVE. The few other similar questions I've found also do not include working answers.
I am unable to find a way to have a ComboBox
display the PromptText
after clearing the selection.
Here is the 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);
}
}
Clicking the "Clear" button will set the selected value to null
and clear the selection of the ComboBox
, but the prompt text does not show again. This does not seem like the normal expected behavior.
I have tried clearSelection()
as well as setPromptText()
within the button's onAction
and nothing seems to work to get the prompt text back.
Upvotes: 4
Views: 5734
Reputation: 209358
According to the documentation, the prompt text should not actually be displayed at all here:
Prompt text is not displayed in all circumstances, it is dependent upon the subclasses of ComboBoxBase to clarify when promptText will be shown. For example, in most cases prompt text will never be shown when a combo box is non-editable (that is, prompt text is only shown when user input is allowed via text input).
If you want to see some prompt text when the selection is null (and you do not have an editable combo box), use a custom buttonCell
on the combo box:
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);
}
}
});
Note that it seems you also need to set the prompt text, as in the code in the question, in order to get the text to appear initially. I assume this is because of the same bug (I'm guessing that the library code is incorrectly setting the text of the button cell to the prompt text initially; if the prompt text is not set, the text gets set to null
, apparently after the button cell's update method is invoked).
And you can obviously make this reusable by creating a named subclass of 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);
}
}
}
and then just
cboSelection.setButtonCell("Select Subject");
cboSelection.setButtonCell(new PromptButtonCell<>("Select Subject"));
Upvotes: 6