gpt4 book ai didi

Javafx 更新对象属性上的 ListCell

转载 作者:行者123 更新时间:2023-12-01 12:20:42 26 4
gpt4 key购买 nike

我正在尝试根据可以在另一个面板中编辑的字段来更新列表单元格的样式类。

我尝试了以下操作,但在编辑文件后,它更改了样式,但也更改了列表中其他 ListCell 的样式。

private ListView<ProviderProduct> importProductsListView  = //Set items in list
importProductsListView.setCellFactory(
new Callback<ListView<ProviderProduct>, ListCell<ProviderProduct>>() {
public ListCell<ProviderProduct> call(ListView<ProviderProduct> param) {
final ListCell<ProviderProduct> cell = new ListCell<ProviderProduct>(){

public void updateItem(ProviderProduct providerProduct, boolean empty){
super.updateItem(providerProduct, empty);

if(!empty) {
setText(providerProduct.toString());

if(providerProduct.hasPriceWarning()){
getStyleClass().add(Consts.CSS_ALERT);
}else{
getStyleClass().remove(Consts.CSS_ALERT);
}

providerProduct.priceListinoProperty().addListener(
new ChangeListener<BigDecimal>() {
@Override
public void changed(ObservableValue<? extends BigDecimal> observable,BigDecimal oldValue, BigDecimal newValue) {

if(providerProduct.hasPriceWarning()){
if(!getStyleClass().contains(Consts.CSS_ALERT)){
getStyleClass().add(Consts.CSS_ALERT);
}
}else{
getStyleClass().removeAll(Collections.singleton(Consts.CSS_ALERT));
}
}
});
}else{
setText("");
getStyleClass().remove(Consts.CSS_ALERT);
}
}
};
return cell;
}
});

最佳答案

我发现您的代码存在两个问题:

首先,styleClass 由一个List 表示,它当然可以保存重复的条目。因此,如果您很不幸,该单元格从一个带有警告的项目重用到另一个带有警告的项目,则最终会导致样式类被添加两次。然后,remove(...) 方法仅删除一个副本,因此当您滚动列表时,您将开始看到不一致的行为。

如果您无法使用 JavaFX 2.2,则需要执行以下操作:

if(providerProduct.hasPriceWarning() & ! getStyleClass().contains(Consts.CSS_ALERT){
getStyleClass().add(Consts.CSS_ALERT);
}else{
getStyleClass().remove(Consts.CSS_ALERT);
}

如果您确实想防弹,确保删除所有出现的情况的方法是使用以下代码代替对 remove(...) 的调用:

getStyleClass().removeAll(Collections.singleton(CSS_ALERT));

如果您可以使用 JavaFX 8(即 Java 8),您可能应该考虑使用 `PseudoClass'相反,这更容易,而且据称更有效。 (另外,使用 lambda 代替所有这些匿名内部类将使您的代码更易于管理。)

其次,每当更新单元格时,您都可以使用该项目的适当属性注册一个监听器。因此,当重复使用单元格来表示新项目时(例如,当用户滚动列表时),它将监听多个项目的属性。您需要根据需要安排删除监听器。

我更喜欢通过创建默认的 ListCell 并观察其 itemProperty() 来解决此问题,因为这使您可以清晰地访问旧项目和新项目当它改变时。所以你可以做这样的事情:

importProductsListView.setCellFactory(
new Callback<ListView<ProviderProduct>, ListCell<ProviderProduct>>() {
public ListCell<ProviderProduct> call(ListView<ProviderProduct> param) {
final ListCell<ProviderProduct> cell = new ListCell<ProviderProduct>();

final ChangeListener<BigDecimal> priceListener = new ChangeListener<BigDecimal>() {
@Override
public void changed(ObservableValue<? extends BigDecimal> observable,BigDecimal oldValue, BigDecimal newValue) {

if(providerProduct.hasPriceWarning()){
if(!getStyleClass().contains(Consts.CSS_ALERT)){
getStyleClass().add(Consts.CSS_ALERT);
}
}else{
getStyleClass().removeAll(Collections.singleton(Consts.CSS_ALERT));
}
}
});

cell.itemProperty().addListener(new ChangeListener<ProviderProduct>() {
@Override
public void changed(ObservableValue<? extends ProviderProduct> obs, ProviderProduct oldProduct, ProviderProduct newProduct) {
if (oldProduct != null) {
oldProduct.priceListinoProperty().removeListener(priceListener);
}
if (newProduct == null) {
cell.setText(null);
cell.getStyleClass().removeAll(Collections.singleton(Consts.CSS_ALERT);
} else {
cell.setText(newProduct.toString());
if (newProduct.hasPriceWarning()) {
if (! cell.getStyleClass().contains(Consts.CSS_ALERT)) {
cell.getStyleClass().add(Consts.CSS_ALERT);
}
} else {
cell.getStyleClass().removeAll(Collections.singleton(Consts.CSS_ALERT));
}
newProduct.priceListinoProperty().addListener(priceListener);
}
}
});

return cell ;
}
});

关于Javafx 更新对象属性上的 ListCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26677697/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com