【问题标题】:JavaFX listview duplication of rendered items when added to observableList添加到 observableList 时呈现项目的 JavaFX listview 重复
【发布时间】:2017-01-25 20:16:56
【问题描述】:

我有一个附有 observableList 的 ListView,

@FXML
private ListView<Weapon> listViewWeapons;

  .... 
  //initialize
  listViewWeapons.setCellFactory(lv -> new CustomWeaponDetailListCell<>());
  listViewWeapons.setItems(CsgoRr.getModel().getWeaponCache());

自定义单元格:

public class CustomWeaponDetailListCell<T extends Weapon> extends ListCell<T> {

    private final StringBuilder sb = new StringBuilder();

    @Override
    public void updateItem(T item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setText(null);
        } else {
            sb.append(item.getName()).append("    Detail:")
                    .append((String) CsgoRr.objectToJsonString(item.getRecoilPattern()));

            setText(sb.toString());
        }
    }
}

创建新武器并将其添加到数据库和列表的功能:

private static int newWeaponNameIncrement = 1;

@FXML
private void newWeaponOnAction() {
    try {
        System.out.println("DEBUG WEAPON NAME TRYING TO BE CREATED IS :" + "newWeapon" + newWeaponNameIncrement);
        Weapon newWeapon = Weapon.createWeapon("newWeapon" + newWeaponNameIncrement,
                new RecoilPattern());
        newWeapon.setId(DbUtil.storeWeapon(newWeapon));

        CsgoRr.getModel().getWeaponCache().add(newWeapon);
    } catch (SQLException ex) {
        if (ex.getErrorCode() == 23505) {//duplicate name
            System.out.println("DEBUG :Duplicate name on add new weapon");
            newWeaponNameIncrement++;
            newWeaponOnAction();
        }

        Logger.getLogger(WeaponViewController.class.getName()).log(Level.SEVERE, null, ex);
    } catch (AWTException ex) {
        Logger.getLogger(WeaponViewController.class.getName()).log(Level.SEVERE, null, ex);
    }
}

一切正常,数据已添加到数据库中,但问题再次在于我如何看待 listView 的行为。问题已证明here in a GIF(GIF 有点太大,您必须单击链接,可以' t 将其嵌入此处)。

正如您从图像中看到的,问题在于它至少在视觉上重复了列表中的项目,因此更改被刷新但不是以正确的方式。一旦我将视图更改为其他内容然后返回,它调用构造函数和初始化方法,一切看起来都应该如此。任何人都知道这是什么问题?

奇怪的部分是我在其他控制器中有类似的代码,它指向我之前的 SO 问题,我没有解决任何问题并且工作完美,但是当我以几乎相同的方式执行此操作时,我在这里得到不同的结果。 JavaFX ListView adding item into observable list doesn't reflect change and it's not selectable 这是一个不同的问题,因为之前我没有任何更新反馈,现在我有反馈但不是正确的。

【问题讨论】:

    标签: java listview user-interface javafx observablelist


    【解决方案1】:

    每次交换项目而不清除它时,您都会重复使用相同的StringBuilder。这意味着生成的String 将是存储在Cell 中的项目的所有值的串联。

    你需要每次使用不同的StringBuilders或者清除StringBuilder

    public class CustomWeaponDetailListCell<T extends Weapon> extends ListCell<T> {
    
        private final StringBuilder sb = new StringBuilder();
    
        @Override
        public void updateItem(T item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
            } else {
                sb.append(item.getName()).append("    Detail:")
                        .append((String) CsgoRr.objectToJsonString(item.getRecoilPattern()));
    
                setText(sb.toString());
    
                // clear StringBuilder content
                sb.delete(0, sb.length());
            }
        }
    }
    

    【讨论】:

    • 天哪,我看着旁边的任何地方都感觉很愚蠢:D,谢谢你注意到它,完全忘了清除它。
    猜你喜欢
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多