setValue(...) 更改组合框保存的值(即,它更改数据或基础模型的状态)。在我看来,你真正想要的只是改变数据的显示方式。您可以通过设置按钮单元来更改所选值的显示。
这是一个示例,其中按钮单元同时跟踪所选项目和页数:
import java.util.Random;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.collections.ListChangeListener.Change;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class PageNumberCombo extends Application {
private static final Random RNG = new Random();
@Override
public void start(Stage primaryStage) {
ComboBox<Integer> combo = new ComboBox<>();
combo.setButtonCell(new ListCell<Integer>() {
{
itemProperty().addListener((obs, oldValue, newValue) -> update());
emptyProperty().addListener((obs, oldValue, newValue) -> update());
combo.getItems().addListener((Change<? extends Integer> c) -> update());
}
private void update() {
if (isEmpty() || getItem() == null) {
setText(null);
} else {
setText(String.format("%d / %d", getItem().intValue(), combo.getItems().size()));
}
}
});
Button reloadButton = new Button("Reload");
reloadButton.setOnAction(e -> reload(combo));
reload(combo);
HBox root = new HBox(10, combo, reloadButton);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(24));
primaryStage.setScene(new Scene(root, 240, 60));
primaryStage.show();
}
private void reload(ComboBox<Integer> combo) {
int numPages = RNG.nextInt(10) + 11 ;
combo.getItems().clear();
IntStream.rangeClosed(1, numPages).forEach(combo.getItems()::add);
}
public static void main(String[] args) {
launch(args);
}
}
如果你的ComboBox是可编辑的,那么按钮单元格默认为TextField,组合框的converter用于将文本字段中的字符串值转换为模型值,反之亦然.所以在这种情况下,您只需要安装一个转换器,它可以在整数x 和字符串"x / total" 之间进行转换。
请注意,默认情况下,此转换器还用于显示下拉单元格中的文本,因此如果您希望这些显示为整数值,则需要安装 cellFactory 以显式创建这些单元格.
import java.util.Random;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class PageNumberCombo extends Application {
private static final Random RNG = new Random();
@Override
public void start(Stage primaryStage) {
ComboBox<Integer> combo = new ComboBox<>();
combo.setEditable(true);
combo.setConverter(new StringConverter<Integer>() {
@Override
public String toString(Integer object) {
return object + " / " + combo.getItems().size();
}
@Override
public Integer fromString(String string) {
int index = string.indexOf('/');
if (index < 0) {
index = string.length();
}
String text = string.substring(0, index).trim();
try {
return Integer.parseInt(text);
} catch (Exception exc) {
return 0 ;
}
}
});
combo.setCellFactory(lv -> new ListCell<Integer>() {
@Override
public void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null) ;
} else {
setText(item.toString());
}
}
});
Button reloadButton = new Button("Reload");
reloadButton.setOnAction(e -> reload(combo));
reload(combo);
HBox root = new HBox(10, combo, reloadButton);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(24));
primaryStage.setScene(new Scene(root, 240, 60));
primaryStage.show();
}
private void reload(ComboBox<Integer> combo) {
int numPages = RNG.nextInt(10) + 11 ;
combo.getItems().clear();
IntStream.rangeClosed(1, numPages).forEach(combo.getItems()::add);
}
public static void main(String[] args) {
launch(args);
}
}