我有一个 Java 8 可编辑组合框,其中默认项目以粗体显示,非默认项目则由 CellFactory 取消粗体显示。 当默认值更改为另一个项目时,我发现 CellFactory 使新的默认值加粗并且旧的默认值取消粗体的唯一方法是删除并重新添加旧的和新的默认值项目。这需要相当多的代码来处理成为当前的新项目,因为先前的当前项目已被删除,然后将当前项目设置为我们正在修改的项目。
有没有一种好的方法可以将单元格标记为脏并需要重新渲染,这样我就不必删除并重新添加 2 个单元格?
我花了半天时间谷歌搜索,但也许我没有问正确的问题。
我想如果我只是清除所有组合框项目并重新添加它们,控制代码会更简单,但这不是很有效。
编辑:根据要求,这里是 CellFactory:
bookComboBox.setCellFactory(
new Callback<ListView<String>, ListCell<String>>() {
@Override public ListCell<String> call(ListView<String> param) {
final ListCell<String> cell = new ListCell<String>() {
{
super.setPrefWidth(100);
}
@Override public void updateItem(String item,
boolean empty) {
super.updateItem(item, empty);
if (item != null) {
setText(item);
if (item.equals(Book.getDefaultBook())) {
setFont(Font.font("System", FontWeight.BOLD, 14));
System.out.println("bookComboBox.setCellFactory: set BOLD item=" + item);
}
else {
setFont(Font.font("System", FontWeight.NORMAL, 14));
System.out.println("bookComboBox.setCellFactory: set NORMAL item=" + item);
}
}
else {
setText(null);
}
}
};
return cell;
}
});
我没有更改单元格的值,只是更改渲染时使用的字体。 我没有使用 onEditCommit()。 我使用 bookComboBox.setOnAction 监听器对组合框选择更改使用react。 当在组合框中输入文本并按下操作键 (ENTER) 或组合框失去焦点时,也会发生 setOnAction 事件。
最佳答案
通过使用 ObservableValue<Boolean>
告诉您每个单元格的项目是否应为粗体,您可以创建一个更新字体的绑定(bind)。
示例:
这将使用每个项目作为默认值 1 秒,然后再使用下一个作为默认值。
@Override
public void start(Stage primaryStage) {
ComboBox<String> comboBox = new ComboBox<>(FXCollections.observableArrayList(
"item 1",
"item 2",
"item 3",
"item 4",
"item 5"
));
final Font BOLD_FONT = Font.font("System", FontWeight.BOLD, 14);
final Font NORMAL_FONT = Font.font("System", FontWeight.NORMAL, 14);
final StringProperty defaultValue = new SimpleStringProperty();
comboBox.setCellFactory(lv -> new ListCell<String>() {
{
// use bold font if the item property contains the
// same value as the defaultValue property
fontProperty().bind(Bindings.when(itemProperty().isEqualTo(defaultValue))
.then(BOLD_FONT)
.otherwise(NORMAL_FONT));
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
setText(item);
}
}
});
// change default every second
PauseTransition animation = new PauseTransition(Duration.seconds(1));
EventHandler<ActionEvent> eventHandler = new EventHandler<ActionEvent>() {
private Iterator<String> iterator = comboBox.getItems().iterator();
@Override
public void handle(ActionEvent event) {
if (!iterator.hasNext()) {
iterator = comboBox.getItems().iterator();
}
defaultValue.set(iterator.next());
animation.play();
}
};
animation.setOnFinished(eventHandler);
eventHandler.handle(null);
Scene scene = new Scene(comboBox);
primaryStage.setScene(scene);
primaryStage.show();
}
关于java - 如何强制重新渲染 JavaFX ComboBox 下拉列表单元格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38213321/