简体   繁体   中英

Get JavaFX TableCell in order to change its style

I'm working on real time data stock gathering, everything works smoothly with real time update on change. I'm not an expert in JavaFX I went through documentation but still not very comfortable with it.

Anyway long story short what I'm trying to do is: Change the style of certain Cell ( Intersection of a Row and Column ) depending on a condition (not worth mentioning or code posting).


I have:

  • class Stock with an attribute variation
  • An observable list ObservableList<Stock> myStocksObservableList contains the data I'm willing to display
  • TableView myStockTable declared as such TableView<Stock> myStockTable;
  • A set of TableColumns with _variation as the column in which I'm interested

Code (front end):

Declaration:

@FXML
private TableView<Stock> mystockTable;
@FXML
private TableColumn<Stock, String> _symbol;
@FXML
private TableColumn<Stock, Float> _open;
@FXML
private TableColumn<Stock, Float> _high;
@FXML
private TableColumn<Stock, Float> _low;
@FXML
private TableColumn<Stock, Float> _close;
@FXML
private TableColumn<Stock, Long> _volume;
@FXML
private TableColumn<Stock, Float> _variation;
@FXML
private TableColumn<Stock, String> _comment;
@FXML
private ObservableList<Stock> myStocksObservableList;

Initialize (let's say myStocksObservableList is already filled with a list of Stock 's:

    _symbol.setCellValueFactory(new PropertyValueFactory<>("symbol"));
    _open.setCellValueFactory(new PropertyValueFactory<>("open"));
    _high.setCellValueFactory(new PropertyValueFactory<>("high"));
    _low.setCellValueFactory(new PropertyValueFactory<>("low"));
    _close.setCellValueFactory(new PropertyValueFactory<>("close"));
    _volume.setCellValueFactory(new PropertyValueFactory<>("volume"));
    _variation.setCellValueFactory(new PropertyValueFactory<>("variation"));
    _comment.setCellValueFactory(new PropertyValueFactory<>("comment"));
     mystockTable.setItems(myStocksObservableList);

How can I add a listener or any such trick that can check a specific TableCell value that will be the intersection of the column _variation and a row I specify, then changes its style accordingly ?

Any solution would be strongly appreciated, any suggestion as well!

If you can provide a ObservableValue<Stock> that contains the item to style (or any other way of storing the info in a way that allows you to add a listener), you can use custom TableRow s to add a pseudoclass to the row and style the cell using an external stylesheet:

ObservableValue<Stock> markedItem = ...;
PseudoClass marked = PseudoClass.getPseudoClass("marked");
_variation.getStyleClass().add("variation");

mystockTable.setRowFactory(tv -> new TableRow<Stock>() {

    private void updatePseudoclass() {
        pseudoClassStateChanged(marked, !isEmpty() && getItem() == markedItem.getValue());
    }

    {
        markedItem.addListener(o -> updatePseudoclass());
    }

    @Override
    protected void updateItem(Stock item, boolean empty) {
        super.updateItem(item, empty);
        updatePseudoclass();
    }

});

CSS stylesheet

.table-row-cell:marked .table-cell.variation {
    -fx-font-style: italic; /* or some other style */
}

I don't think there is a way to directly get a table cell and modify it.

However, you can try to create a CellFactory that changes the cell's properties (eg style) according to the updates of the cell.

Callback factory = new Callback<TableColumn<String[], String>, TableCell<String[], String>>() {
    @Override
    public TableCell<String[], String> call(TableColumn<String[], String> param)
    {
        return new TableCell<String[], String>() {
            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);

                // depending on item's value do something. . .
                // for instance, if item == 'bla' change cell color 
                // this.setStyle(.....)

                // don't forget to set item's text
                setText(item);
            }
        };
    }
};

// your table data in the from of String[][] where the first row holds the column titles
//String[][] data = ...
tableView.getColumns().clear();
tableView.getItems().clear();

// populating the tableView
for (int rowIndex = 0 ; rowIndex < data.length ; rowIndex++)
{
    for (int columnIndex = tableView.getColumns().size(); columnIndex < data[rowIndex].length; columnIndex++)
    {
        TableColumn<String[], String> column = new TableColumn<>();
        final int index = columnIndex;
        column.setCellFactory(factory); // Important line
        column.setCellValueFactory(cellData -> {
            String[] row = cellData.getValue();
            String value = row[index];
            return new SimpleStringProperty(value);
        });
        tableView.getColumns().add(column);
    }
    tableView.getItems().add(data[rowIndex]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM