有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

数据分配给JavaFX后,java无法从TableView检索所有行

我有一个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)

共 (3) 个答案

  1. # 1 楼答案

    ObservableList<yourData> data =table.getItems();
    
    for(yourData yd : data) {
        //your action
    }
    
  2. # 2 楼答案

    JavaFX视图(表/树/列表/…)是虚拟的,只创建屏幕上显示的节点数。因此,无论我的域项目如何,您都会将TableRow对象的数量推到与屏幕上显示的行数相当的位置(可能有一个视图缓冲区)

  3. # 3 楼答案

    不能为表视图“检索行”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伪类而不是普通的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... *.
    }