JavaFX table column different font with css


Question

I want to set a different font ( well actually just italics ) in one column of a JavaFX table.
I've seen this answered by calling setCellFactory and then setting the font on that. In my view ( which with JavaFX has been regularly wrong ;-) ) this is quite an involved and messy way to do the job - if you want to deal with editing on the cell etc. you end up with a large class instead of just using something like

col.setCellFactory(TextFieldTableCell.<TableRow>forTableColumn());

So, my question is this - has anyone managed to set an id or style class on the column and reference that in css?

My attempt was something like this ( trying both class and id ):

col.getStyleClass().add(colDef.isItalic()? "italic-cell" : null);
col.setId(colDef.isItalic()? "italic-cell" : null);

and then using some combination of

#italic-cell
.italic-cell
#special-table .italic-cell

etc. etc. with

-fx-font-style: italic;

as the style for the ID / class

1
3
7/29/2017 10:31:47 PM

Accepted Answer

CSS Styling of Table Columns

Add an appropriate style class to your column:

nameColumn.getStyleClass().add("italic");

Add a stylesheet to your scene which defines the italic style for table cells:

.italic.table-cell { -fx-font-style: italic; }

Caveat 1

I tried this example again based on T-and-M Mike's comments and indeed it didn't quite work right on OS X 10.9 with Java 8. I believe, on windows just setting the -fx-font-style to italic allowed the text to show in italic. On a Mac, this will set the font to System Italic, which is a font which does not seem to exist, so the text just displays without italics. If you also set the font family to some font for which italics are defined, then the text in the column will show in italic as expected. For example, use Times New Roman, italic:

.italic.table-cell { 
  -fx-font-family: "Times New Roman"; 
  -fx-font-style: italic; 
}

Caveat 2

On Java 8b132 on OS X 10.9, there is a slight rendering bug when the table is first displayed where the table content is slightly out of line with the table headers.

Calling table.requestLayout(); after the table was shown on the screen seemed to fix the alignment rendering bug for the table, but if everything was working right, the call wouldn't be necessary.

Executable Sample

Test output result on Win7 + Java 8b91:

payees

CellShadedTable.java

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

// demonstrates styling column cells in a tableview.
public class CellShadedTable extends Application {
  public static void main(String[] args) throws Exception { launch(args); }
  @Override public void start(final Stage stage) throws Exception {
    stage.setTitle("So called friends . . .");

    // create a table.
    TableColumn<Friend, String> nameColumn = new TableColumn<>("Name");
    nameColumn.setCellValueFactory(new PropertyValueFactory<Friend, String>("name"));
    nameColumn.setPrefWidth(75);
    nameColumn.getStyleClass().add("italic");

    TableColumn<Friend, String> owesMeColumn = new TableColumn<>("Owes Me");
    owesMeColumn.setCellValueFactory(new PropertyValueFactory<Friend, String>("owesMe"));
    owesMeColumn.setPrefWidth(150);

    TableColumn<Friend, Boolean> willPayColumn = new TableColumn<>("Will Pay Up");
    willPayColumn.setCellValueFactory(new PropertyValueFactory<Friend, Boolean>("willPay"));
    willPayColumn.setPrefWidth(75);

    TableView<Friend> table = new TableView(Friend.data);
    table.getColumns().addAll(
      nameColumn,
      owesMeColumn,
      willPayColumn
    );
    table.setPrefHeight(200);
    table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

    stage.setScene(new Scene(table));
    stage.getScene().getStylesheets().add(getClass().getResource("cell-shader.css").toExternalForm());
    stage.show();

    table.requestLayout();
  }
}

Friend.java

import javafx.collections.*;

/** Sample data for a table view */
public class Friend {
  final static public ObservableList data = FXCollections.observableArrayList(
    new Friend("George", "Movie Ticket", true),
    new Friend("Irene", "Pay Raise", false),
    new Friend("Ralph", "Return my Douglas Adams Books", false),
    new Friend("Otto", "Game of Golf", true),
    new Friend("Sally", "$12,045.98", false),
    new Friend("Antoine", "Latte", true)
  );

  final private String  name;
  final private String  owesMe;
  final private boolean willPay;
  public Friend(String name, String owesMe, boolean willPay) {
    this.name = name; this.owesMe = owesMe; this.willPay = willPay;
  }
  public String  getName()    { return name;    }
  public String  getOwesMe()  { return owesMe;  }
  public boolean getWillPay() { return willPay; }
}

cell-shader.css

/** file: cell-shader.css
place in same directory as CellShadedTable.java */

.italic.table-cell { 
  -fx-font-family: "Times New Roman";
  -fx-font-style: italic; 
}

Cell Factory Based Approach

For reference (and as shown above, not necessary for simple styling operations), information on a custom TableCell based approach to row coloring is in:

7
5/23/2017 11:54:28 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon