JavaFX TableView with Custom Cell Datepicker "OnEditCommit" is not invoked


Question

Hi everyone !!

I'm working with JavaFX and the JDK 8.

I got a TableView filled by a database with the use of a JavaFX POJO Class "Inputs". I've implemented TexField cells, ComboBoxes cells and Checkbox cells succesfully.

But I am not able to make it working with DatePicker Control: the event on the "setOnEditComit" is never invoked...

Hre is my code:

Declarations for TableColumn:

    @FXML
    private TableColumn<Inputs,LocalDate> colDate = new TableColumn<Inputs,LocalDate>();
     [...]
    colDate.setCellValueFactory(
                        new PropertyValueFactory<Inputs,LocalDate>("localdate"));

        Callback<TableColumn<Inputs, LocalDate>, TableCell<Inputs, LocalDate>> dateCellFactory =
                    new Callback<TableColumn<Inputs, LocalDate>, TableCell<Inputs, LocalDate>>() {
                public TableCell call(TableColumn p) {
                    return new EditingDatePickerCell();
                }
            };

      [...]
    colDate.setOnEditCommit(
                    new EventHandler<CellEditEvent<Inputs, LocalDate>>() {
                        @Override
                        public void handle(CellEditEvent<Inputs, LocalDate> event) {

        System.out.println("EVENT!!!!");
                            ((Inputs) event.getTableView().getItems().get(
                                    event.getTablePosition().getRow())
                                    ).setDatePicker(event.getNewValue());
   }
   }
   );

With these JavaFX POJO Objects declarations:

    public ObjectProperty<LocalDate> localdate; 
     [...]

     this.localdate =  new SimpleObjectProperty<LocalDate>(localdate); 
     [...]
    public LocalDate  getDatePicker() {
            return localdate.getValue();
        }
     [...]
    public void setDatePicker(LocalDate  value) {
            System.out.println("EVENT!!!!");
            localdate.setValue(value);
        }
     [...]
    public ObjectProperty<LocalDate> localdateProperty() {
            return localdate;
        }

EditingDatePickerCell class:

 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;

 import javafx.application.Platform;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.geometry.Pos;
 import javafx.scene.control.ContentDisplay;
 import javafx.scene.control.DatePicker;
 import javafx.scene.control.TableCell;
 import javafx.scene.control.TableColumn;
 import javafx.scene.input.KeyCode;
 import javafx.scene.input.KeyEvent;

 import com.desktop.newapp.utils.Inputs;

    public class EditingDatePickerCell <Inputs, LocalDate> extends TableCell<Inputs, LocalDate> {

        @Override
        public void startEdit() {
            if (!isEmpty()) {
                super.startEdit();
                createDatePicker();
                setText(null);
                setGraphic(datePicker);
                datePicker.requestFocus();
            }
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();
            datePicker.setValue((java.time.LocalDate) getItem());
            setGraphic(null);
            setContentDisplay(ContentDisplay.TEXT_ONLY);
        }

        private DatePicker datePicker;

        public EditingDatePickerCell() {
            if (datePicker == null) {
                createDatePicker();
            }
            setGraphic(datePicker);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);

            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    datePicker.requestFocus();
                }
            });
        }

        @Override
        public void updateItem(LocalDate item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {

            if (datePicker != null && item != null) {
                datePicker.setValue((java.time.LocalDate) getLocalDate());
                commitEdit(getLocalDate());
            }
                setGraphic(datePicker);
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);

            }
        }


        private void createDatePicker() {
            datePicker = new DatePicker();
            datePicker.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
            setGraphic(datePicker);  



            datePicker.addEventFilter(KeyEvent.KEY_PRESSED,new EventHandler<KeyEvent>() { 
                @Override
                public void handle(KeyEvent t) {

                        if (t.getCode() == KeyCode.ENTER) {
                            commitEdit(getLocalDate());
                        } else if (t.getCode() == KeyCode.ESCAPE) {
                            cancelEdit();
                        } else if (t.getCode() == KeyCode.TAB) {
                            commitEdit(getLocalDate());;

                        }
                    }

            });

            setAlignment(Pos.CENTER);
        }

        private LocalDate getLocalDate() {
       return  getItem();
         ///return datePicker.getValue() != null ? datePicker.getValue() : getItem();
        }  
    }

I've been Googling a lot and I didn't find any correct implementation of the Java8 DatePicker Editing capabilities in a JavaFX TableView. Any help would be very appreciate !!

Without Stackoverflow I'll never could done the quarter of the whole job so long life to Stackoverflow !!

Regards.

1
0
3/25/2014 3:37:21 PM

You need to put the table in editing mode (for the current row) when the user interacts with the picker. That can be achieved with an onShowingHandler like this (example is also with a color picker):

this.colorPicker.setOnShowing(event -> {
    final TableView<T> tableView = getTableView();
    tableView.getSelectionModel().select(getTableRow().getIndex());
    tableView.edit(tableView.getSelectionModel().getSelectedIndex(), column);       
});

then watch the valueProperty of the picker like this:

this.colorPicker.valueProperty().addListener((observable, oldValue, newValue) -> {
    if(isEditing()) {
        commitEdit(newValue);
    }
}); 

For more explanation have a look at my blog post: Custom editor components in JavaFX TableCells.

Full Class:

public class ColorTableCell<T> extends TableCell<T, Color> {    
    private final ColorPicker colorPicker;

    public ColorTableCell(TableColumn<T, Color> column) {
    this.colorPicker = new ColorPicker();
    this.colorPicker.editableProperty().bind(column.editableProperty());
    this.colorPicker.disableProperty().bind(column.editableProperty().not());
    this.colorPicker.setOnShowing(event -> {
        final TableView<T> tableView = getTableView();
        tableView.getSelectionModel().select(getTableRow().getIndex());
        tableView.edit(tableView.getSelectionModel().getSelectedIndex(), column);       
    });
    this.colorPicker.valueProperty().addListener((observable, oldValue, newValue) -> {
        if(isEditing()) {
        commitEdit(newValue);
        }
    });     
    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    }

    @Override
    protected void updateItem(Color item, boolean empty) {
    super.updateItem(item, empty);  

    setText(null);  
    if(empty) {     
        setGraphic(null);
    } else {        
        this.colorPicker.setValue(item);
        this.setGraphic(this.colorPicker);
    } 
    }
}
2
8/23/2017 3:42:59 AM

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