2016-09-29 92 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

您的更新很棒!再次感谢这个快速而深刻的答案。 –