的问题主要出现是因为你最终改变可观察名单(选择模型的selectedItems
),而结束正在处理该列表中的更改。这在API中是一个缺陷,imo。一种解决方法(黑客)是一个Platform.runLater(...)
使用过滤列表,并更新谓词的名单上,这样才能让第一个变化再次改变之前完成:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ComboBoxNoSelectedItem extends Application {
@Override
public void start(Stage primaryStage) {
ObservableList<String> allItems = FXCollections.observableArrayList("One", "Two", "Three", "Four", "Five");
ComboBox<String> combo = new ComboBox<>();
combo.setValue(allItems.get(0));
FilteredList<String> items = allItems.filtered(item -> item != combo.getValue());
combo.setItems(items);
combo.valueProperty().addListener((obs, oldValue, newValue) -> Platform.runLater(() -> items.setPredicate(item -> item != newValue)));
BorderPane root = new BorderPane();
root.setTop(combo);
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
也许一个更简洁的方法就是到禁用显示当前选中的项目,这是接近的细胞,但不完全一样,UX:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ComboBoxNoSelectedItem extends Application {
@Override
public void start(Stage primaryStage) {
ObservableList<String> allItems = FXCollections.observableArrayList("One", "Two", "Three", "Four", "Five");
ComboBox<String> combo = new ComboBox<>(allItems);
combo.setCellFactory(lv -> new ListCell<String>() {
{
disableProperty().bind(combo.valueProperty().isEqualTo(itemProperty()));
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(item);
}
});
BorderPane root = new BorderPane();
root.setTop(combo);
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
如果删除所选的项目,那么显然选择将不得不改变。你究竟想在这里发生什么? (为什么你改变选择的变化列表?) –
我想显示在组合框值我选择的项目,但我希望该项目从列表中删除,所以当我再次点击该组合框它会显示为所有选项,除了已经选择的选项 –