In method setOnEditCommit() of TableColumn i trty to change the color of cell's text and it does no effect. It is TableView wih only one row. here mycode...What i'm doing wrong ?
columnnumberofsession.setOnEditCommit(event -> {
try {
ffnumberofsession.checkValue(event.getNewValue());
}
catch(IllegalArgumentException iae) {
System.err.println("The value for number of session is invalid !");
event.getTableColumn().setStyle("-fx-text-fill: red;");
return;
}
event.getTableColumn().setStyle("-fx-text-fill: black;");
System.out.println("Value is correct.");
});
I try the method ouside of <setOnEditCommin()> callback and it's work well. The color of text change but it is a static test. I want the color of cell text become red when i catch an error. I don't see why it doesn't work inside setOnEditCommit().
What you are doing wrong
I'm not exactly sure, but on the other hand I am not sure why what you are doing would work either.
No you don't, I mean not directly.
You call:
to change the column's fill style, not the cell's fill style.
The column is a different thing from the cell.
I did try testing this, if you have a
TableViewand aTableColumnobject and you call:myTableColumn.setStyle("-fx-text-fill: red;");on the column it will change the style of all the labels in the cells in the column (but not the table header) to red.
This is unrelated to editing and matches what Estienne states when he mentions
I just don't know how and why that actually works though. As far as I can tell the behavior of styling table cells via styling the columns is not documented in the CSS reference guide.
What may be going wrong with your approach
Usually, with editing in the
TableView, there are multiple nodes involved in the cell implementation and the nodes switch in and out of view depending on whether the cell is being edited or not. This may be interfering with the undocumented behavior for styling text cell fills by setting styles on the column. That is just my speculation though.Suggested approach
Usually for these state change styles, instead of setting styles directly in code, it is better practice, more configurable and more robust to apply and remove style classes (or pseudo classes) together with stylesheets with appropriate rules defined.
For example in the updateItem for the cell, check if the session is invalid, and if so ensure the cell has the session-invalid style class, otherwise ensure it does not.
Then define the styling for the session-invalid style class in your CSS stylesheet. You might need an extractor on the observable items list to get the update to fire.
If necessary a separate property can be defined for the items backing the TableView (or a global property if the state of the entire TableView is affected), and that property can indicate the styles to apply when the items are updated. In this case, an additional property is probably not necessary as the validation check can be performed in updateItem.
Example snippets demonstrating the suggested approach
CSS styling (you can define this in an external stylesheet, I just defined it inline to cut down on files):
Custom text field table cell which applies styling when the cell data is invalid. In this case it will be invalid if the email column is edited not to include an
@symbol in the email.The table needs to be made editable too:
When the items list backing the table is defined, an extractor is set on the email data so that the email cells will be updated when the email changes:
The outcome will be that, if you double click a cell, edit its value and change it to something invalid (e.g. remove the
@symbol from the email), the cell will be highlighted in red until it is fixed.Example App
Output after editing one of the emails to make the value invalid:
This remaining information is supplemental to the core answer above. If the answer is too long and the information below is not relevant to your situation, then ignore it.
FAQ
Changing the header color is an also possible, but I didn't want to include an implementation for that in this answer. It wasn't clear to me if that was part of the original question, plus the implementation for that will be a bit different.
Unless somebody else provides a supplemental answer about header styling to this question, check to see if there is a duplicate of the header question on StackOverflow. If not, then you may wish ask to ask a new question on dynamic header styling.
Additional info on styling columns
As noted by James in comments on this question, there is some inbuilt undocumented logic in the table cells where the cells copy some of the style information from the column styles.
However the style copying logic in the cells from column styles is only partial (and I don’t think it copies styles to the column header fields):
You could rely on the undocumented logic for copying style information from columns to cells. But it may not work as expected in some situations (such as your edit commit case in the question). If it is not working, I'd discourage trying to create bandaid workarounds to get it to work for your case. Instead directly and explicitly style the individual table cells (like in this answer) and column headers (not covered in detail in this answer).
Supplementary info on styling table column headers
As also noted by James in comments:
This was my finding too. The inheritance mode for various CSS styles is not all that clearly documented. One might think that because a table cell is inside a table column that it would just automatically inherit the column's styles. But that is not the case for non-inherited styles.
By default CSS styles are not inherited:
And the implementation of the
-fx-fillstyle does not set the inherits property to true, so it does not inherit.That is why I was confused that setting the fill on the column actually changed the cell style in the case where editing is not involved. It is because of the hidden style copying in the TableView implementation that James refers to in his comment.
However James did outline an approach to styling the header explicitly which should work (I didn't try it):
Also note, that, unlike the fill color, the -fx-font-* CSS styles do inherit. So, if you set the font size, weight, italics or family on the column, the font changes for both the header labels and all the cells in the column. Which can be somewhat surprising if you don't quite understand what is really going on :-)