Search code examples
cssjavafxtableviewjavafx-8tablecelleditor

Create A Validity Check For TextFieldTableCell in JavaFX


I have some TextFieldTableCell which are for taking Double data type values. I want to validate them. If user give wrong data type as input or keep that field empty, I want to mark that TextFieldTableCell as

Background color Yello

Text style color Red

At the end of successful validation, I want that TextFieldTableCell normal again.

How can I make this happen?


Solution

  • Well you could achieve with soo many ways, and the so many ways has to do with the way you implement it in the TableCell, but it will be mainly dependent on the DataHolder Object you use to help with the virtualization

    To do this you will have to create your TableCell's updateItem(Object,boolean) to implement the updating of the cell with respect to styles, etc, and it should be in relation with your updateSelected(boolean) even though one calls the other, or leave the two and use updateIndex() so something like this for your DataHolder class

    private class CellDataHolder {
    
        public CellDataHolder (String a){
            value = a;
        }
    
        String value = "empty"; //this being the text to show
        boolean badMatch = false; //this being the flag to index whether the
        //text matches your preference
    }
    

    now in your cell, in one of those methods mentioned you add a check for your item for example

    @Override
        public void updateItem(CellDataHolder item, boolean empty) {
            super.updateItem(item, empty);
            if(empty){return;}
            setText(item.value);//set your text
            if(item.badMatch){//check if the text fits.
                setStyle(wrongFormatStyle);//this is where you set your bad style
            }else{
                setStyle(normalyStyle);//the style you want
            }
        }
    

    and then in your StringConverter you will use that to check whether your text is valid the reason you i feel you should use the StringConverter is that it can reduce the multiple calls update...() receives, those methods gets called soo many times is not cool to put a long much work there, your cell might look slow, so its better you put it here, for example

    setConverter(new StringConverter<CellDataHolder>() {
                @Override
                public String toString(CellDataHolder arg0) {
                        arg0.badMatch =
                                arg0.value.matches(".*[a-zA-Z]+.*");//here you add your algorithm
                    return arg0.value;
                }
    
                @Override
                public CellDataHolder fromString(String arg0) {
                    getItem().value = arg0;
                    return getItem();
                }
            });
    

    you can also filter how filter when the check is to be called, whether a refresh is called or an explicit edit is being made. for example

    setConverter(new StringConverter<CellDataHolder>() {
                @Override
                public String toString(CellDataHolder arg0) {
                     if(isEditing()){ //whether it is an edit
                        arg0.badMatch =
                                arg0.value.matches(".*[a-zA-Z]+.*");//here you add your algorithm
                     }
                    return arg0.value;
                }
    
                @Override
                public CellDataHolder fromString(String arg0) {
                    getItem().value = arg0;
                    return getItem();
                }
            });
    

    Here is a full demo snippet

    demo preview enter image description here

    Hope it helps.