Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The setPromptText() function doesn't work after selecting an item for the 2nd time or more in JavaFX

Tags:

java

javafx

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

enter image description here

Then let's say I choose 2 items corresponding to those 2 comboboxes enter image description here

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

enter image description here

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>
like image 649
Cat Dragon Avatar asked Dec 14 '25 06:12

Cat Dragon


1 Answers

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.

like image 192
James_D Avatar answered Dec 16 '25 18:12

James_D



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!