【问题标题】:JavaFX TableView scrolling colors different row that aren't ment to be coloredJavaFX TableView滚动颜色不同的行不应该被着色
【发布时间】:2020-03-19 15:04:46
【问题描述】:

论坛,

我创建了一个表格视图。每一行都填充了每个“Steckerpin”对象给出的信息。使用 RowFactory 我根据每个对象(“Steckerpin”)的属性“Zusand”的值对每行的背景进行着色。

问题是,当表格变得可滚动时,新出现的行的颜色顺序与开头的颜色行相似。但是这些行不应该被着色,因为它们的属性“Zusand”没有改变。

Colored rows before scrolling

New appearing rows after scrolling

如果我滚动到表格的末尾,错误颜色的行会再次变为白色。

我已经读到,将 tableviews 与 RowFactory 结合使用是一个常见问题,因为一旦开始滚动,就会重复使用这些行。

这是我使用 RowFactory 的代码:

durchgangsTable.setRowFactory(tv -> new TableRow<Steckerpin>() {

    @Override
    public void updateItem(Steckerpin item, boolean empty) {
        super.updateItem(item, empty);

        if (item == null || empty) {
            setGraphic(null);
            setStyle("");
        } else if (item.getZustand().equals(okZustString)) {
            pseudoClassStateChanged(PseudoClass.getPseudoClass("ok"), true);
        } else if (item.getZustand().equals(fehlerZustString)) {
            pseudoClassStateChanged(PseudoClass.getPseudoClass("error"), true);
        } else if (item.getZustand().equals(prüfZustString)) {
            pseudoClassStateChanged(PseudoClass.getPseudoClass("pending"), true);
        }
    }
});

我已经阅读了几个类似的问题,但我找不到我的问题的解决方案。因此,我将非常感谢您的帮助。

【问题讨论】:

标签: javafx scroll tableview background-color tablerow


【解决方案1】:

当您滚动时,现有行会被重新用于显示新项目。因此,例如,如果您有一行显示处于“错误”状态的项目,并且它被重用于处于“正常”状态的项目,那么两个伪类都将设置为true

因此,您需要在所有条件下将所有伪类设置为正确的状态:

durchgangsTable.setRowFactory(tv -> new TableRow<Steckerpin>() {

    @Override
    public void updateItem(Steckerpin item, boolean empty) {
        super.updateItem(item, empty);

        if (item == null || empty) {
            setGraphic(null);
            setStyle("");
            pseudoClassStateChanged(PseudoClass.getPseudoClass("ok"), false);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("error"), false);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("pending"), false);
        } else if (item.getZustand().equals(okZustString)) {
            pseudoClassStateChanged(PseudoClass.getPseudoClass("ok"), true);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("error"), false);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("pending"), false);
        } else if (item.getZustand().equals(fehlerZustString)) {
            pseudoClassStateChanged(PseudoClass.getPseudoClass("ok"), false);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("error"), true);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("pending"), false);
        } else if (item.getZustand().equals(prüfZustString)) {
            pseudoClassStateChanged(PseudoClass.getPseudoClass("ok"), false);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("error"), false);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("pending"), true);
        } else {
            pseudoClassStateChanged(PseudoClass.getPseudoClass("ok"), false);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("error"), false);
            pseudoClassStateChanged(PseudoClass.getPseudoClass("pending"), false);
        }
    }
});

同样,代码更少:

durchgangsTable.setRowFactory(tv -> new TableRow<Steckerpin>() {

    private final List<String> states = List.of("ok", "error", "pending");

    @Override
    public void updateItem(Steckerpin item, boolean empty) {
        super.updateItem(item, empty);

        if (item == null || empty) {
            setGraphic(null);
            setStyle("");
            updateState(null);
        } else if (item.getZustand().equals(okZustString)) {
            updateState("ok");
        } else if (item.getZustand().equals(fehlerZustString)) {
            updateState("error");
        } else if (item.getZustand().equals(prüfZustString)) {
            updateState("pending");
        } else {
            updateState(null);
        }
    }

    private void updateState(String newState) {
        states.forEach(state ->
            pseudoClassStateChanged(PseudoClass.getPseudoClass(state), state.equals(newState)));
    }

});

【讨论】:

  • 嘿,首先感谢您的快速回答。不幸的是,这并没有解决问题,但是这种对伪类进行编码的方式非常好。
  • @KSchenk 再次检查:我注意到解决方案中有一个错误并刚刚更新它。
  • @KSchenk 您使用的是哪个 Java 版本?这是在 Java 9 中引入的。(我假设您导入了 java.util.List。)如果您仍在使用早期版本,则可以使用 Arrays.asList(...)
  • 我目前正在使用 Java 8
  • 所以Arrays.asList(...) 应该代替List.of(...)。 (或者第一个版本,带有重复的语句,也应该可以工作。)
猜你喜欢
  • 2016-04-05
  • 2018-10-12
  • 1970-01-01
  • 2021-01-02
  • 2014-06-29
  • 1970-01-01
  • 2013-08-07
  • 2020-01-29
  • 2015-08-08
相关资源
最近更新 更多