在为JavaFX分配数据后,无法从TableView检索所有行
我有一个TableView,其中已经分配了一堆数据。在这之后,我想循环遍历所有行,检查一些条件,然后根据该条件使用CSS绘制每个行。为什么以下内容会产生IndexOutOfBoundsException?相反,我为什么不检索我想要的行?为什么我创建的数组是空的在为JavaFX分配数据后,无法从TableView检索所有行,java,javafx,tablerow,Java,Javafx,Tablerow,我有一个TableView,其中已经分配了一堆数据。在这之后,我想循环遍历所有行,检查一些条件,然后根据该条件使用CSS绘制每个行。为什么以下内容会产生IndexOutOfBoundsException?相反,我为什么不检索我想要的行?为什么我创建的数组是空的 int i = 0; for (Node n: tableViewPriority.lookupAll("TableRow")) { System.out.println(n);
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)
JavaFX视图(表/树/列表/…)是虚拟的,只创建屏幕上显示的节点数。因此,无论我的域项目是如何推送TableRow对象的数量,推送的行数与您在屏幕上看到的行数相当(可能有一个视图缓冲区)JavaFX视图(表/树/列表/…)都是虚拟的,只创建屏幕上看到的节点数。因此,无论“我的域项目”如何推送TableRow对象的数量,推送的行数与您在屏幕上看到的行数相当(可能存在视图缓冲区)您都无法为表视图“检索行”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");
}
}
});
然后在外部CSS文件中,您可以执行以下操作:
。表格行单元格:低{
/*低优先级的样式…*。
}
无法为表视图“检索行”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");
}
}
});
然后在外部CSS文件中,您可以执行以下操作:
。表格行单元格:低{
/*低优先级的样式…*。
}
可观察列表数据=table.getItems();
对于(您的数据yd:数据){
//你的行动
}
可观察列表数据=table.getItems();
对于(您的数据yd:数据){
//你的行动
}
if(tableViewPriority.getItems().get(I)…)行中出现的异常(我假设该异常)指示tableViewPriority.getItems()为空。但是,正如回答中所指出的,这种方法根本不起作用(即使您先填充表):一旦您开始滚动表视图,所有行都将没有正确的样式。使用rowFactory
。是的,我尝试使用rowFactory,但检索行时遇到问题。我需要包含数据的行来应用条件。您不能“检索行”。这就是答案中提出的要点。您需要创建在调用updateItem()
方法时更新其样式的行。您应该显示您使用行工厂所做的尝试。异常(我假设发生在行中,如果(tableViewPriority.getItems().get(I)…)
)指示tableViewPriority.getItems()
为空。但是,正如回答中所指出的,这种方法根本不起作用(即使您先填充表):一旦您开始滚动表视图,所有行都将没有正确的样式。使用rowFactory
。是的,我尝试使用rowFactory,但检索行时遇到问题。我需要包含数据的行来应用条件。您不能“检索行”。这就是答案中提出的要点。您需要创建在调用updateItem()
方法时更新其样式的行。您应该展示您使用行工厂所做的尝试。是的,使用伪状态是正确的方法,也是最有效的方法!是的,使用伪状态是正确的方法,也是最有效的方法!请详细说明这是解决方案的原因。请
ObservableList<yourData> data =table.getItems();
for(yourData yd : data) {
//your action
}