Suppose I have 2 ComboBoxes like these, and they show prompt text.

Then let's say I choose 2 items corresponding to those 2 comboboxes

However, upon reselecting the Front-end, the second combobox lost its prompt text, despite me having set the prompt text using setPromptText()

How can I do that? Here is my Application file
package com.example.demo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HelloApplication extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
try{
Parent root = FXMLLoader.load(this.getClass().getResource("test.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}catch (Exception e){
System.out.println(e);
}
}
}
Here is the Controller file
package com.example.demo;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import java.net.URL;
import java.util.ResourceBundle;
public class Test implements Initializable {
@FXML
public ComboBox<String> DevelopmentType;
@FXML
public ComboBox<String> LanguageProgramming;
ObservableList<String> listDevelopmentType = FXCollections.observableArrayList("Back-end", "Front-end");
ObservableList<String> listLanguageProgrammingBackEnd = FXCollections.observableArrayList("Java", "PHP");
ObservableList<String> listLanguageProgrammingFrontEnd = FXCollections.observableArrayList("HTML", "CSS", "Javascript");
@Override
public void initialize(URL location, ResourceBundle resources) {
DevelopmentType.setItems(listDevelopmentType);
}
public void DevelopmentTypeEvent(){
if(DevelopmentType.getValue().equals("Back-end")){
LanguageProgramming.setPromptText("Select a language programming");//Not working
LanguageProgramming.setItems(listLanguageProgrammingBackEnd);
}
else if(DevelopmentType.getValue().equals("Front-end")){
LanguageProgramming.setPromptText("Select a language programming");//Not working
LanguageProgramming.setItems(listLanguageProgrammingFrontEnd);
}
}
}
Here is the FXML file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demo.Test">
<children>
<ComboBox fx:id="DevelopmentType" layoutX="75.0" layoutY="62.0" onAction="#DevelopmentTypeEvent" prefHeight="26.0" prefWidth="218.0" promptText="Select a development type" />
<ComboBox fx:id="LanguageProgramming" layoutX="75.0" layoutY="98.0" prefHeight="26.0" prefWidth="217.0" promptText="Select a language programming" />
</children>
</AnchorPane>
The use of prompt text in a combo box is not well documented. The API documentation says, somewhat vaguely:
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
The implementation seems patchy, as the question notes. The prompt text appears not to be supported in non-editable mode, with the exception of the initial display.
The (mostly) more robust approach here is to use a custom button cell (which is used to configure the display of the combo box button):
public class Test implements Initializable {
@FXML
public ComboBox<String> DevelopmentType;
@FXML
public ComboBox<String> LanguageProgramming;
ObservableList<String> listDevelopmentType = FXCollections.observableArrayList("Back-end", "Front-end");
ObservableList<String> listLanguageProgrammingBackEnd = FXCollections.observableArrayList("Java", "PHP");
ObservableList<String> listLanguageProgrammingFrontEnd = FXCollections.observableArrayList("HTML", "CSS", "Javascript");
@Override
public void initialize(URL location, ResourceBundle resources) {
DevelopmentType.setItems(listDevelopmentType);
LanguageProgramming.setButtonCell(new ListCell<String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null || item.isEmpty()) {
setText("Select a programming language");
} else {
setText(item);
}
}
});
}
public void DevelopmentTypeEvent(){
if(DevelopmentType.getValue().equals("Back-end")){
LanguageProgramming.setItems(listLanguageProgrammingBackEnd);
}
else if(DevelopmentType.getValue().equals("Front-end")){
LanguageProgramming.setItems(listLanguageProgrammingFrontEnd);
}
}
}
This also seems slightly broken: it doesn't by itself properly set the text on the initial display. If you keep the initial setting of the prompt text in the FMXL, it seems to work the way you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With