如何重置 JavaFX ComboBox 值并重新显示提示文本

How to reset JavaFX ComboBox value and re-show prompt text

基本上我想要的只是有一个“清除”按钮,按下该按钮会清除一些 TextFields 和 ComboBox 的值,并使它们再次显示提示文本。 TextFields 工作正常,但 ComboBox 仅在第一次显示其提示文本,一旦我清除它就不会再次显示。

我在那里发现了一个类似的问题,但答案是重置选择并将值设置为 null,这是控制器的最小可重现示例 class:

package sample;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable{

    @FXML ComboBox<String> testBox;
    
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        testBox.getItems().addAll("Item 1", "Item 2");
    }

    public void clear(ActionEvent event) {
        testBox.getSelectionModel().clearSelection();
        testBox.setValue(null);
    }
}

FXML 文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <ComboBox fx:id="testBox" layoutX="225.0" layoutY="187.0" prefWidth="150.0" promptText="TEST" />
      <Button layoutX="274.0" layoutY="255.0" mnemonicParsing="false" onAction="#clear" text="Clear" />
   </children>
</AnchorPane>

哪个没用(提示文本不再出现)所以我来了。

根据 documentation,组合框如果不可编辑则不应显示提示文本。所以它在开头显示提示文本的事实似乎是一个错误。

如果你想强制它在为空且不可编辑时显示提示文本,你可以使用自定义按钮单元格来实现:

public void initialize() {
    testBox.setButtonCell(new ListCell<>() {
        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(testBox.getPromptText());
            } else {
                setText(item);
            }
        }
    });
    testBox.getItems().addAll("Item 1", "Item 2");
}