Open Siedlerchr opened 6 years ago
Your validator setup looks good but I think the setup of the cellfactory is not correct.
You are initializing the visualizer for one cell-value and one specific cell. However, JavaFX is reusing cells for different values. It will only create as many cells as needed for one view of elements in the table and it will reuse them when the user scrolls down.
The setup of a cellFactory
and cellValueFactory
is unconnected in JavaFX. The cellValueFactory
only defines how a value to display is resolved. The cellFactory
defines which type of cells is used. However, the cellFactory doesn't know anything about actual values.
Your setup is only possible because you are nesting both factory methods. Normally you don't define the cellValueFactory
inside a cellFactory
method.
Ok, so how to fix this? I have to admit that I haven't used the validation within a TableView yet. The basic assumption of the validation module is that there is a one-to-one connection between a value and a control in the view (which is typically the case for forms). This assumption isn't true for Tables so we have to find a workaround.
In TableCell
there is a method updateItem
which is invoked everytime the value of a cell is updated.
A typicall pattern is to create a subclass (can be anonymous inner class) and override this method. This would probably be the correct place to update the validation but I don't know hot to access the actual value (the StringViewModel
instance in your example) inside of this method. And I don't know if this would create any sideeffects.
I don't have a ready-to-use solution but I'm trying to find one.
I found a solution that seems to work but I haven't fully tested it and I don't know if there are any negative side-effects. But you could try it out:
colContent.setCellValueFactory(cellData -> cellData.getValue.getContent());
colContent.setCellFactory(column -> new TextFieldTableCell<StringViewModel, String>(new DefaultStringConverter()) {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(! empty) {
if(getTableRow() != null) {
Object rowItem = getTableRow().getItem();
if(rowItem != null && rowItem instanceof StringViewModel) {
StringViewModel vm = (StringViewModel) rowItem;
visualizer.initVisualization(vm.contentValidation(), this);
}
}
}
}
});
With this setup I get the validation marks in the table cells. However, the default styling of ControlsFX seems to be not optimal for this usecase. Due to the fact that TextFieldTableCell
renders a Label
when the value was entered, there is no red border but only a small mark at the buttom left corner of the TableCell.
Another limitation is that it doesn't validate the inital values but only after the user has changed the value in the table.
Yeah cool! Thanks for the help, I will try this out. In JabRef we have a custom icon decorater that hopefully looks better.
The only odd effect I encounter is the following: Clear the first column cell -> icon shows Clear the second column cell -> The first icon is gone , the icon shows for the second cell But, when I now click the button to enter a new row, then both icons are shown again. Seems like a redraw is then triggered.
I don't know the internals of how and when re-render is done in JavaFX TableViews. Maybe there are examples or documentation of how the ControlsFX validation can be used with Tables? The visualization part of mvvmFX validation is quite similar to the one from ControlsFX, just with a different API. So maybe if they have any hints on how this works with pure ControlsFX then we probably can adapt the solution.
I have created a very simple TableView with two columns and added a ValidiationVisualizer to the TextFieldTableCell. The validation triggers correctly, but there is no visual clue shown. I tried different Decorators etc. but I could not figure it out. Any help would be appreciated!
This is the code I used to setup the table:
https://github.com/JabRef/jabref/pull/3735/files#diff-117aa7fc99c0b7380bdaf11022bb3575
In my ViewModel I have the Validator:
https://github.com/JabRef/jabref/pull/3735/files#diff-df16f2f707ba7bfd296b444ac7962c20