我正在尝试将JavaFX ComboBox
用作具有历史记录的搜索字段。
这是我的代码示例。
ObservableList<String> patternHistory = FXCollections.observableArrayList();
searchComboBox.setItems(patternHistory);
searchComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
ObservableList<String> history = searchComboBox.getItems();
// This works fine
// history.add(newValue);
// This does not work
history.add(0, newValue);
});
如果我执行history.add(newValue)
,ComboBox
的行为与我预期的一样。
历史记录中的最后一个条目将添加到列表的末尾。
但是,我希望首先显示最后一个条目(我还想删除重复项并限制历史记录大小,但在本例中我保持简单)。
所以我决定只用history.add(0, newValue)
在列表前添加新值。
但是,当我这样做时,组合框开始以奇怪的方式运行,代码不再起作用。似乎只要我在列表的末尾添加/删除项目就可以正常工作,但如果我在开头或中间做同样的事情,它就不再起作用了。
这里我使用lambda表达式语法,但我尝试使用匿名类表示法,它是相同的。我也试图实现我自己的可观察列表,也有同样的结果。
我目前正在使用JDK 1.8.0_60,但我遇到了早期版本的问题。 有人可以告诉我是否有办法解决这个问题或者我做错了什么?
答案 0 :(得分:1)
解决方法似乎是替换列表中的所有项目。以下似乎工作正常:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HistoryListComboBox extends Application {
@Override
public void start(Stage primaryStage) {
ComboBox<String> combo = new ComboBox<>();
combo.getItems().addAll("One", "Two", "Three");
combo.setEditable(true);
combo.valueProperty().addListener((obs, oldValue, newValue) -> {
if (! combo.getItems().contains(newValue)) {
List<String> newItems = new ArrayList<>();
newItems.add(newValue);
newItems.addAll(combo.getItems());
combo.getItems().setAll(newItems);
}
});
StackPane root = new StackPane(combo);
primaryStage.setScene(new Scene(root, 350, 120));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}