2017-06-16 59 views
0

我有一個TableView,其中有一堆已分配給它的數據。在此之後,我想遍歷所有行,檢查一些條件,然後根據該條件使用CSS爲每個條件繪製。爲什麼以下產生IndexOutOfBoundsException?相反,爲什麼我不檢索我想要的行?爲什麼我創建的數組是空的?無法從數據分配後從TableView中檢索所有行JavaFX

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) 
+0

例外(我假設(tableViewPriority.getItems()。get(i)...)')表示'tableViewPriority.getItems()'是空的。但正如答案中所指出的那樣,這種方法根本不起作用(即使您先填充表格):一旦開始滾動表格視圖,沒有任何行將具有正確的樣式。使用'rowFactory'。 –

+0

是的,我嘗試過使用RowFactory,但我無法檢索行。我需要包含數據的行來應用條件。 – santafebound

+0

你不能「檢索行」。答案就是這一點。您需要創建行,以便在調用updateItem()方法時更新其樣式。您應該顯示您使用行工廠進行的嘗試。 –

回答

2

您無法「檢索行」一張桌子視圖。 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... *. 
} 
+0

是的,使用pseudoState是正確的方法,也是性能最好的方法! – tomsontom

1

JavaFX的視圖(表/樹/列表/ ...)是虛擬的,只作爲創建屏幕上看到儘可能多的節點。因此,無論您的Domain-Items如何將您在屏幕上看到的相同數量的行中推送的TableRow對象的數量(可能存在視圖的緩衝區)