You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX TableView滚动时错误着色非目标行问题求助

解决TableView行复用导致的样式错误问题

嘿,这个问题我太熟悉了!你猜得没错,就是TableRow复用机制在搞鬼——当表格滚动时,已经渲染过的行对象会被重新分配给新的数据项,但你当前的代码只在匹配到特定Zustand时设置伪类状态,却没有在切换数据时重置这些状态,旧的样式就被“继承”给新行啦。

问题出在哪?

你现在的代码逻辑是:如果item符合某个状态,就把对应的伪类设为true,但完全没处理“不符合时把伪类设回false”的情况。比如之前某行被标记为ok状态,当它被复用给一个状态为默认的item时,ok伪类还是true,所以样式就错了。

修复方案

每次调用updateItem时,先重置所有相关的伪类状态,再根据当前item的属性设置正确的状态。这样不管行怎么复用,都能保证样式和当前绑定的数据一致。

修改后的代码如下:

durchgangsTable.setRowFactory(tv -> new TableRow<Steckerpin>() {
    private final PseudoClass okPseudo = PseudoClass.getPseudoClass("ok");
    private final PseudoClass errorPseudo = PseudoClass.getPseudoClass("error");
    private final PseudoClass pendingPseudo = PseudoClass.getPseudoClass("pending");

    @Override
    public void updateItem(Steckerpin item, boolean empty) {
        super.updateItem(item, empty);
        
        // 第一步:重置所有伪类状态,清除旧样式残留
        pseudoClassStateChanged(okPseudo, false);
        pseudoClassStateChanged(errorPseudo, false);
        pseudoClassStateChanged(pendingPseudo, false);

        if (item == null || empty) {
            setGraphic(null);
            setStyle("");
        } else {
            String zustand = item.getZustand();
            if (zustand.equals(okZustString)) {
                pseudoClassStateChanged(okPseudo, true);
            } else if (zustand.equals(fehlerZustString)) {
                pseudoClassStateChanged(errorPseudo, true);
            } else if (zustand.equals(prüfZustString)) {
                pseudoClassStateChanged(pendingPseudo, true);
            }
            // 这里可以保留setGraphic,如果你有需要的话
        }
    }
});

关键修改点说明

  • 提前定义三个伪类对象,避免每次调用都重复创建,提升性能
  • 在处理当前item之前,强制把三个伪类都设为false,彻底清除旧状态
  • 逻辑上更清晰:先清零,再根据当前数据设置正确状态

这样修改后,不管表格怎么滚动,行的样式都会和绑定的Steckerpin对象的Zustand属性完全匹配,不会再出现错误着色的问题啦!

内容的提问来源于stack exchange,提问作者K Schenk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:47:47