【问题标题】:Cannot retrieve all rows from TableView after data assigned JavaFX数据分配 JavaFX 后无法从 TableView 中检索所有行
【发布时间】:2017-06-16 10:22:00
【问题描述】:

我有一个 TableView,其中已经分配了一堆数据。在此之后,我想遍历所有行,检查一些条件,然后根据该条件用 CSS 绘制每一行。为什么以下会产生 IndexOutOfBoundsException?相反,为什么我不检索我想要的行?为什么我创建的数组是空的?

    int i = 0;
        for (Node n: tableViewPriority.lookupAll("TableRow")) {
            System.out.println(n);
            if (n instanceof TableRow) {
                TableRow row = (TableRow) n;
                System.out.println(row);
                if (tableViewPriority.getItems().get(i).getPriority().equals("Low")) {
                    row.getStyleClass().add("tableViewGreen");
                }
                i++;
                if (i == tableViewPriority.getItems().size())
                    break;
            }
        }

例外:

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
    at app.controller.TableViewController.populateTable(TableViewController.java:356)
    at app.controller.TableViewController.organizeTable(TableViewController.java:318)
    at app.controller.TableViewController.assignTicketsToTable(TableViewController.java:236)
    at app.controller.TableViewController.lambda$null$0(TableViewController.java:202)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

  • 异常(我假设发生在if (tableViewPriority.getItems().get(i)...) 行)表明tableViewPriority.getItems() 为空。但是,如答案所示,这种方法根本行不通(即使您先填充表格):一旦开始滚动表格视图,所有行都不会具有正确的样式。使用rowFactory
  • 是的,我尝试过使用 RowFactory,但我在检索行时遇到了麻烦。我需要其中包含数据的行来应用条件。
  • 您不能“检索行”。这就是答案中的重点。您需要创建在调用 updateItem() 方法时更新其样式的行。您应该展示您使用行工厂所做的尝试。

标签: java javafx tablerow


【解决方案1】:

您不能为表格视图“检索行”。 TableRow 实例仅为表中的可见 项创建(不适用于表中滚动到视图之外的项),并且这些TableRow 实例可以重复用于其他项,例如例如,如果用户滚动表格。

因此,通常表中的大多数项目不会有与之关联的行,并且任何行显示的项目可能会发生变化,例如当用户滚动表格时。此外,可以在程序运行时的任意时间创建新的TableRow 实例,例如,如果用户增加应用程序窗口的大小并为表格分配更多空间(因此可见更多项目)。

因此,您使用的方法 - 即使在您尝试执行您发布的代码之前将数据添加到表视图中 - 也根本不起作用。样式只会应用于当前可见的行,并且如果用户滚动表格(或由于某些其他原因重复使用这些行),则会突出显示错误的行(因为您的代码无法检查该行何时更新用于新项目)。

(此外,您无法保证查找会以正确的顺序返回表行实例。)

相反,指定一个行工厂,在其项目更新时更新行的样式:

tableViewPriority.setRowFactory(tv -> new TableRow<SomeClass>() {

    @Override
    protected void updateItem(SomeClass item, boolean empty) {
        super.updateItem(item, empty); 
        if (item!=null && "Low".equals(item.getPriority())) {
            if (! getStyleClass().contains("tableViewGreen")) {
                getStyleClass().add("tableViewGreen");
            }
        } else {
            getStyleClass().remove("tableViewGreen");
        }
    }
});

显然将SomeClass 替换为您的表格显示的任何类型。

请注意,使用 CSS PseudoClass 而不是普通的 CSS 类可能更简洁:

PseudoClass low = PseudoClass.getPseudoClass("low");

tableViewPriority.setRowFactory(tv -> new TableRow<SomeClass>() {

    @Override
    protected void updateItem(SomeClass item, boolean empty) {
        super.updateItem(item, empty); 
        pseudoClassStateChanged(low, item!=null && "Low".equals(item.getPriority()));
    }
});

然后在你的外部 CSS 文件中你可以这样做:

.table-row-cell:low {
    /* styles for low priority... *.
}

【讨论】:

  • 是的,使用伪状态是正确的方法,也是最高效的方法!
【解决方案2】:

JavaFX-Views (Table/Tree/List/...) 是虚拟的,只创建与屏幕上看到的一样多的节点。因此,无论我的 Domain-Items 如何将 TableRow 对象的数量推送到屏幕上几乎相同的行数(可能存在视图缓冲区)

【讨论】:

    【解决方案3】:
    ObservableList<yourData> data =table.getItems();
    
    for(yourData yd : data) {
        //your action
    }
    

    【讨论】:

    • 请详细说明为什么这是解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多