2016-09-29 91 views
1

。它接觸到css僞類「:filled」被觸發,儘管單元格應該是空的。我無法弄清楚,如果相關的cellValueFactory missbehaves,或者如果有錯誤的地方。當我在JavaFX8 TableView中上下滾動時,越來越多的單元格被錯誤着色,JavaFX TableView觸發css「:filled」 - 滾動上的僞類

this is how it looks after scrolling a while

的.css

error-cell:filled { 
    -fx-background-color: #ff3333; 
    -fx-text-fill: white; 
    -fx-opacity: 1; 
} 

.fxml

<BorderPane fx:id="projectList" stylesheets="@../css/projectList.css,@../css/tables.css" xmlns="http://javafx.com/javafx/8.0.45" xmlns:fx="http://javafx.com/fxml/1" fx:controller="my.package.ProjectListController"> 
    <center> 
     <TableView fx:id="projectListTableView"> 
      <columnResizePolicy> 
       <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /> 
      </columnResizePolicy> 
      <columns> 

       <TableColumn fx:id="errorCol" styleClass="error-cell" text="Error"> 
        <cellValueFactory> 
         <PropertyValueFactory property="error" /> 
        </cellValueFactory> 
       </TableColumn> 

      </columns> 
     </TableView> 
    </center> 
</BorderPane> 

的.java

public class ProjectListController 
{ 
    @FXML 
    private TableView<ProjectWrapper> projectListTableView; 

    @FXML 
    private TableColumn<ProjectWrapper, String> errorCol; 

    private ObservableList<ProjectWrapper> projectTable = FXCollections.observableArrayList(); 

    // dummy-method that fills projectTable, normally it's a db-query 
    public void fillErrorColumn() 
    { 
     ProjectWrapper pw = new ProjectWrapper(); 
     pw.setError("1/0/0"); 
     this.projectTable.add(pw); 
    } 


    public void populateTable() 
    { 
     try 
     { 
      projectListTableView.setItems(this.projectTable); 
     } 
     catch (Exception e) 
     { 
      logger.error("", e); 
     } 
    } 

} 

你們誰能想到導致出現此問題的一個原因?或者一種確保在滾動期間單元格保持空白的方式?


順便說一句,我寧可不設置額外的cellValueFactory,因爲有太多類似的指標。我也嘗試過徒勞 - 這意味着相同的結果。

private void setCellFactoryErrorCol() 
{ 
    errorCol.setCellFactory(column -> 
    { 
     return new TableCell<ProjectWrapper, String>() 
     { 
      @Override 
      protected void updateItem(String item, boolean empty) 
      { 
       super.updateItem(item, empty); 

       if (item != null && item.length() > 2) 
       { 
        setText(item); // ohne setText() bleibt das Feld 
            // leer - wird nicht automatisch von 
            // super gesetzt 
        getStyleClass().add("error-cell"); 
        setTooltip(new Tooltip("All/In work/Fixed")); 
       } 
       else 
       { 
        setText(null); 
        setStyle(""); 
       } 
      } 
     }; 
    }); 
} 

非常感謝!


編輯1 我可以通過使用代碼 「James_D」 S'的回答解決我的問題。 即使我寧願使用CSS。


編輯2 爲了最小化祿,並提升整體的可維護性,我創建了一個utilityClass我控制器的初始化過程中調用。

public class CellFactoryUtil 
{ 

    public <E> void setCellFactoryStringErrorCol(TableColumn<E, String> errorCol) 
    { 
     PseudoClass errorPC = PseudoClass.getPseudoClass("error-pc"); 

     errorCol.setCellFactory(column -> new TableCell<E, String>() 
      { 
       @Override 
       protected void updateItem(String item, boolean empty) 
       { 
        super.updateItem(item, empty); 

        if (item != null && item.length() > 2) 
        { 
         setText(item); 
         pseudoClassStateChanged(errorPC, true); 
         setTooltip(new Tooltip("All/In work/Fixed")); 
        } 
        else 
        { 
         setText(null); 
         pseudoClassStateChanged(errorPC, false); 
        } 
       } 
      } 
     ); 
    } 
} 

我正在使用泛型,因爲程序有幾個不同包裝的表。還有很多代碼,但它工作得很好!

+0

那麼,你仍然在使用CSS解決方案,不是嗎?如果沒有單元工廠(工具提示,並且不顯示長度<= 2的值),您在單元工廠中還有其他功能,因此您已經需要單元工廠。不確定你最喜歡做什麼。 –

回答

0

對於CSS,您正在將樣式類應用於TableColumn:它不太清楚該如何工作。 JavaFX CSS guide中沒有關於TableColumn的文檔。要做到這一點的方法是在細胞工廠。

請注意,:filled僞類正好與:empty相反:即除了表中的實際具有數據的行之下的空的「空間填充」單元以外的所有單元都是如此。對於在行中有數據的所有單元,即使單元數據是null(當然如果單元數據是空字符串),:filled應爲true

在您的單元工廠實現中,您絕不會從樣式類列表中刪除"error-cell"樣式類。而且,在滾動時,您可能會將字符串"error-cell"的多個副本添加到樣式類列表中(可能導致內存泄漏)。

你需要像

errorCol.setCellFactory(column -> 
{ 
    return new TableCell<ProjectWrapper, String>() 
    { 
     @Override 
     protected void updateItem(String item, boolean empty) 
     { 
      super.updateItem(item, empty); 

      if (item != null && item.length() > 2) 
      { 
       setText(item); // ohne setText() bleibt das Feld 
           // leer - wird nicht automatisch von 
           // super gesetzt 
       if (! getStyleClass().contains("error-cell")) { 
        getStyleClass().add("error-cell"); 
       } 
       setTooltip(new Tooltip("All/In work/Fixed")); 
      } 
      else 
      { 
       setText(null); 
       setStyle(""); // not sure this line does anything: you never set the style anyway... 
       getStyleClass().remove("error-cell"); 
      } 
     } 
    }; 
}); 

注意,這可能是清潔劑來創建自己的這個僞類,而不是操縱樣式類:

PseudoClass errorPC = PseudoClass.getPseudoClass("error"); 

errorCol.setCellFactory(column -> new TableCell<ProjectWrapper, String>() { 

    @Override 
    protected void updateItem(String item, boolean empty) 
    { 
     super.updateItem(item, empty); 

     if (item != null && item.length() > 2) 
     { 
      setText(item); // ohne setText() bleibt das Feld 
          // leer - wird nicht automatisch von 
          // super gesetzt 
      pseudoClassStateChanged(errorPC, true); 
      setTooltip(new Tooltip("All/In work/Fixed")); 
     } 
     else 
     { 
      setText(null); 
      pseudoClassStateChanged(errorPC, false); 
     } 
    } 

}); 

,然後CSS看起來像

.table-cell:error { 
    -fx-background-color: #ff3333; 
    -fx-text-fill: white; 
    -fx-opacity: 1; 
} 
+0

謝謝你的回答。它以多種方式幫助我! –

+0

查看更新以獲得稍微乾淨的方法。 –

+0

您的更新很棒!再次感謝這個快速而深刻的答案。 –