TableView仅修改每个单元格的样式

时间:2018-08-23 14:54:27

标签: javafx tableview

假设一个:

{ "ls", "wc" }

在TableColumn中,我们有setCellValueFactory方法,该方法很好地使您可以访问相应单元格值的ResultType对象。因此,您可以使用它来提取类似的值:

TableView<ResultType, String> table = new TableView<> ();
table.setItems(myItems);

现在,aColumnFromTableView中的每个单元格都将填充来自所有ResultType对象的值,这些对象被设置为表的项目。

问题是:我们还可以以类似方式更改单元格的样式吗?我看了一下setCellFactory方法,但是它看起来不像setCellValueFactory友好(=它没有提供相应的ResultType)。

这是使用setCellFactory可以做的事情:

aColumnFromTableView.setCellValueFactory(data -> new SimpleStringProperty(data.getValue));

所以我想知道一种类似于我在“ setCellValueFactory”中描述的方式来单独设置单元格样式的方法。我希望它存在。

注意:我也尝试过

aColumnFromTableView.setCellValueFactory(data -> ???? ); // data is actually aColumnFromTableView itself?? 

但这会为整个列而不是单独设置它。

谢谢!!!!

1 个答案:

答案 0 :(得分:1)

如果要基于单元格的值自定义TableCell的样式,则需要使用cellFactory并返回自己的TableCell

例如,如果您想让TableCell<?, Double>在数字为负数时显示为红色,则可以这样做:

column.setCellFactory(col -> new TableCell<>() {
  @Override 
  protected void updateItem(Double item, boolean empty) {
    super.updateItem(item,  empty);
    if (empty || item == null) {
      setText(null);
      setGraphic(null);
    } else {
      setText(item.toString());
      if (item < 0.0) {
        setTextFill(Color.RED); // or use setStyle(String)
      } else {
        setTextFill(Color.BLACK); // or use setStyle(String)
      }
    }
  }
});

创建自定义TableCell时,您很可能会想覆盖updateItem(Object,boolean)方法。重要的是,正确地覆盖它,但是,如果您希望它正常工作。阅读javadoc以获取信息:

  

updateItem方法不应由开发人员调用,但这是开发人员重写以允许他们自定义单元格外观的最佳方法。为了明确起见,开发人员永远不要在代码中调用此方法(他们应将其留给UI控件,例如ListView控件)来调用此方法。但是,拥有updateItem方法的目的是使开发人员在指定自定义单元工厂(同样,如ListView单元工厂)时,可以重写updateItem方法以允许对单元进行完全自定义。

     

非常重要非常重要,因为Cell的子类正确覆盖了updateItem方法,否则将导致诸如空白单元格或其中包含意外内容的单元格之类的问题。这是一个如何正确覆盖updateItem方法的示例:

protected void updateItem(T item, boolean empty) {
    super.updateItem(item, empty);

    if (empty || item == null) {
        setText(null);
        setGraphic(null);
    } else {
        setText(item.toString());
    } 
}
     

此代码示例中的两个要点:

     
      
  1. 我们称为super.updateItem(T,boolean)方法。如果不这样做,则item和empty属性设置不正确,最终可能会遇到图形问题。
  2.   
  3. 我们测试是否为空,如果为true,则将text和graphic属性设置为null。如果我们不这样做,几乎可以保证最终用户会意外地看到单元中的图形工件。
  4.   

您可以使用PseudoClass状态之类的方法来代替设置属性或调用setStyle,以便更轻松地从外部CSS样式表进行样式设置。

import javafx.css.PseudoClass;
import javafx.scene.control.TableCell;

public class CustomCell<S> extends TableCell<S, Double> {

  private static final PseudoClass POSITIVE = PseudoClass.getPseudoClass("positive");
  private static final PseudoClass NEGATIVE = PseudoClass.getPseudoClass("negative");

  public CustomCell() {
    getStyleClass().add("custom-cell");
  }

  @Override
  protected void updateItem(Double item, boolean empty) {
    super.updateItem(item, empty);
    if (empty || item == null) {
      setText(null);
      setGraphic(null);
      pseudoClassStateChanged(POSITIVE, false);
      pseudoClassStateChanged(NEGATIVE, false);
    } else {
      setText(item.toString()); // you might want to format the number for display
      pseudoClassStateChanged(POSITIVE, item >= 0.0);
      pseudoClassStateChanged(NEGATIVE, item < 0.0);
    }
  }
}

然后使用:

column.setCellFactory(col -> new CustomCell<>());

在样式表中:

.custom-cell:positive {
  -fx-text-fill: black;
}

.custom-cell:negative {
  -fx-text-fill: red;
}