diff --git a/gemsfx-demo/src/main/java/com/dlsc/gemsfx/demo/SelectionBoxApp.java b/gemsfx-demo/src/main/java/com/dlsc/gemsfx/demo/SelectionBoxApp.java index 5ad26deb..b02ceeac 100644 --- a/gemsfx-demo/src/main/java/com/dlsc/gemsfx/demo/SelectionBoxApp.java +++ b/gemsfx-demo/src/main/java/com/dlsc/gemsfx/demo/SelectionBoxApp.java @@ -64,6 +64,17 @@ private Node getControlPanel() { CheckBox visibleExtraButtonsCheckBox = new CheckBox("Show Extra Buttons"); visibleExtraButtonsCheckBox.selectedProperty().bindBidirectional(selectionBox.showExtraButtonsProperty()); + // prompt text + CheckBox promptTextCheckBox = new CheckBox("Change Prompt Text"); + promptTextCheckBox.setOnAction(evt -> { + selectionBox.getSelectionModel().clearSelection(); + if (promptTextCheckBox.isSelected()) { + selectionBox.setPromptText("Select"); + } else { + selectionBox.setPromptText("No Selection"); + } + }); + // change extra buttons Button changeExtraButtonsButton = new Button("Change Extra Buttons"); changeExtraButtonsButton.setMaxWidth(Double.MAX_VALUE); @@ -213,6 +224,7 @@ public List fromString(String string) { "SelectionBox", new SimpleControlPane.ControlItem("Show Popup", showButton), new SimpleControlPane.ControlItem("Selection Mode", selectionModeComboBox), + new SimpleControlPane.ControlItem("Change Prompt Text", promptTextCheckBox), new SimpleControlPane.ControlItem("Show Extra Buttons", visibleExtraButtonsCheckBox), new SimpleControlPane.ControlItem("Change Extra Buttons", changeExtraButtonsButton), new SimpleControlPane.ControlItem("Extra Buttons Position", extraButtonsPositionComboBox), diff --git a/gemsfx/src/main/java/com/dlsc/gemsfx/SelectionBox.java b/gemsfx/src/main/java/com/dlsc/gemsfx/SelectionBox.java index 43557cb7..55fe2ff1 100644 --- a/gemsfx/src/main/java/com/dlsc/gemsfx/SelectionBox.java +++ b/gemsfx/src/main/java/com/dlsc/gemsfx/SelectionBox.java @@ -8,6 +8,8 @@ import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleListProperty; import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.css.CssMetaData; @@ -156,7 +158,7 @@ public final void setExtraButtonsProvider(Callback, Li * The button will be styled with the "extra-button" class and will adjust its visibility * based on its managed property. The button's maximum width will be set to the maximum double value. * - * @param text the text to be displayed on the button + * @param text the text to be displayed on the button * @param action the action to be executed when the button is clicked * @return the created Button instance */ @@ -169,9 +171,9 @@ public Button createExtraButton(String text, Runnable action) { * The created button will be styled with "extra-button" class and will adjust its visibility * based on its managed property. The button's maximum width will be set to the maximum double value. * - * @param text the text to be displayed on the button + * @param text the text to be displayed on the button * @param graphic the graphic node to be displayed on the button - * @param action the action to be executed when the button is clicked + * @param action the action to be executed when the button is clicked * @return the created Button instance */ public Button createExtraButton(String text, Node graphic, Runnable action) { @@ -253,6 +255,31 @@ public final Node getGraphic() { return graphic == null ? null : graphic.get(); } + // promptText + + private StringProperty promptText; + + /** + * Returns the prompt text property of this SelectionBox. The prompt text is an optional + * text that can be displayed in the picker when no item is selected. + * + * @return the StringProperty containing the prompt text. + */ + public final StringProperty promptTextProperty() { + if (promptText == null) { + promptText = new SimpleStringProperty(this, "promptText"); + } + return promptText; + } + + public final void setPromptText(String promptText) { + promptTextProperty().set(promptText); + } + + public final String getPromptText() { + return promptText == null ? null : promptText.get(); + } + // autoHideOnSelection private BooleanProperty autoHideOnSelection; @@ -301,6 +328,9 @@ public final void setAutoHideOnSelection(boolean autoHideOnSelection) { * this list to display as "1, 2, 3, 4, 5". By setting a custom converter, it is possible to modify * the display to any desired format, such as "1~5". *

+ * If the selected items list is {@code null} or empty, the {@code promptTextProperty()} value will + * be used instead, so there is no need to handle these cases within the converter. + *

* The {@code selectedItemsConverterProperty} provides a way to bind the display logic to UI components, * enabling dynamic updates whenever the selected items change or the converter is redefined. * diff --git a/gemsfx/src/main/java/com/dlsc/gemsfx/skins/SelectionBoxSkin.java b/gemsfx/src/main/java/com/dlsc/gemsfx/skins/SelectionBoxSkin.java index 372a021b..5a312c64 100644 --- a/gemsfx/src/main/java/com/dlsc/gemsfx/skins/SelectionBoxSkin.java +++ b/gemsfx/src/main/java/com/dlsc/gemsfx/skins/SelectionBoxSkin.java @@ -119,6 +119,7 @@ private void addListenerToControl() { control.itemConverterProperty().addListener((obs, oldConverter, newConverter) -> updateDisplayLabelText()); control.selectedItemsConverterProperty().addListener((obs, oldConverter, newConverter) -> updateDisplayLabelText()); + control.promptTextProperty().addListener((obs, oldText, newText) -> updateDisplayLabelText()); control.getSelectionModel().selectedItemProperty().addListener(selectItemChangedListener); control.getSelectionModel().getSelectedItems().addListener(selectItemsChangeListener); @@ -227,11 +228,16 @@ public void updateDisplayLabelText() { StringConverter> stringConverter = control.getSelectedItemsConverter(); String text; - if (stringConverter != null) { - text = stringConverter.toString(selectedItems); + + if (selectedItems.isEmpty()) { + text = control.getPromptText(); } else { - // Use default conversion logic - text = getDefaultDisplayText(selectedItems); + if (stringConverter != null) { + text = stringConverter.toString(selectedItems); + } else { + // Use default conversion logic + text = getDefaultDisplayText(selectedItems); + } } displayLabel.setText(text); } @@ -384,7 +390,7 @@ private class SelectionPopupSkin implements Skin { public SelectionPopupSkin(SelectionPopup popup) { this.popup = popup; - contentBox = new VBox(){ + contentBox = new VBox() { @Override public String getUserAgentStylesheet() { return Objects.requireNonNull(SelectionBox.class.getResource("selection-box.css")).toExternalForm();