title: Why does DatePicker become unresponsive after a startEdit() in a custom JavaFX 11 TableCell?
body: <p>I have a <code>TableCell</code> that renders a date as a <code>DatePicker</code> when editing and as plain text when not editing.</p>
  
  <p>When the <code>TableCell</code> is edited, the <code>DatePicker</code> should receive focus, its date should be selected and the cursor should be in the editor at the end of the date.  The <code>DatePicker</code>'s editor should then be ready to accept user input.</p>
  
  <p>However, at the moment, when the cell is edited, the <code>DatePicker</code> gets focus but it (or its editor?) becomes unresponsive.  The date isn't selected and the cursor is nowhere in sight.  I can't click into the editor nor type anything into the editor.  The only thing that works is the button that shows the calendar popup.</p>
  
  <p>Further, this <em>only happens the first time a <code>DatePicker</code> cell is edited in a given row</em>.  The next time the same cell in the same row is edited, it works fine.</p>
  
  <p>It also works fine if I change <code>setContentDisplay()</code> to GRAPHIC_ONLY in <code>updateItem()</code> but I don't want to do that.</p>
  
  <p>Below is a MVCE that demonstrates the issue.</p>
  
  <p>To reproduce the behaviour, either double-click on a date cell or use the arrow keys to navigate to it and press F2.  The <code>DatePicker</code> will get focus but its date will not be selected and you won't be able to click into the <code>DatePicker</code>'s editor.</p>
  
  <p>Now click anywhere off the date cell and then go back to the same cell in the same row and edit it a second time.  The date should then be selected and you should be able click or type into the editor.</p>
  
  <p>What am I doing wrong?</p>
  
  <p>I've Googled and found examples of <code>DatePicker</code>s in <code>TableView</code>s but all set content display to GRAPHIC_ONLY in <code>updateItem()</code>.  I've not been able to find any that use TEXT_ONLY except while editing.</p>
  
  <p>I'm using the 11.0.2 versions of OpenJDK and OpenJFX running in Netbeans 11.0 on Windows 7.</p>
  
  <pre><code>package test016;
  
  import java.time.LocalDate;
  import java.time.format.DateTimeFormatter;
  import java.util.Arrays;
  import javafx.application.Application;
  import static javafx.application.Application.launch;
  import javafx.beans.property.ObjectProperty;
  import javafx.beans.property.SimpleObjectProperty;
  import javafx.beans.property.SimpleStringProperty;
  import javafx.beans.property.StringProperty;
  import javafx.collections.FXCollections;
  import javafx.collections.ObservableList;
  import javafx.scene.Parent;
  import javafx.scene.Scene;
  import javafx.scene.control.ContentDisplay;
  import javafx.scene.control.DatePicker;
  import javafx.scene.control.TableCell;
  import javafx.scene.control.TableColumn;
  import javafx.scene.control.TableView;
  import javafx.scene.control.cell.TextFieldTableCell;
  import javafx.scene.layout.BorderPane;
  import javafx.stage.Stage;
  import javafx.util.StringConverter;
  import javafx.util.converter.DefaultStringConverter;
  
  public class Test016 extends Application {
  
      private final ObservableList&lt;DataModel&gt; ol = FXCollections.observableArrayList();
      private final TableView&lt;DataModel&gt; tv = new TableView();
  
      private Parent createContent() {
  
          loadDummyData();
  
          createTableViewColumns();
  
          tv.getSelectionModel().setCellSelectionEnabled(true);
          tv.setEditable(true);
          tv.setItems(ol);
          tv.getSelectionModel().selectFirst();
  
          BorderPane content = new BorderPane();
          content.setCenter(tv);
  
          return content;
      }
  
      private void createTableViewColumns() {
  
          TableColumn&lt;DataModel,String&gt; col1 = new TableColumn&lt;&gt;("field1");
          TableColumn&lt;DataModel,LocalDate&gt; col2 = new TableColumn&lt;&gt;("field2");
          TableColumn&lt;DataModel,String&gt; col3 = new TableColumn&lt;&gt;("field3");
  
          col1.setCellValueFactory(cellData -&gt; cellData.getValue().field1Property());
          col1.setCellFactory(TextFieldTableCell.&lt;DataModel, String&gt;forTableColumn(new DefaultStringConverter()));
  
          col2.setCellValueFactory(cellData -&gt; cellData.getValue().field2Property());
  
          //**************************************************************
          //DatePicker TableCell begins here
  
          col2.setCellFactory(dp -&gt; {
  
              DatePicker datePicker = new DatePicker();
  
              StringConverter&lt;LocalDate&gt; dateConverter = new StringConverter&lt;LocalDate&gt;() {
                  @Override
                  public String toString(LocalDate object) {
                      DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/MM/yyyy");
                      return ( object == null ? "" : dateFormatter.format(object) );
                  }
  
                  @Override
                  public LocalDate fromString(String string) {
                      DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/MM/yyyy");
                      return string.isEmpty() ? null : LocalDate.parse(string, dateFormatter);
                  }
  
              };
  
              datePicker.setConverter(dateConverter);
              datePicker.setEditable(true);
              datePicker.setDisable(false);
  
              TableCell&lt;DataModel, LocalDate&gt; cell = new TableCell&lt;&gt;() {
  
                  @Override
                  protected void updateItem(LocalDate item, boolean empty) {
  
                      super.updateItem(item, empty);
  
                      if (empty) {
                          setText(null);
                          setGraphic(null);
                      } else {
                          //It works I set content display to GRAPHIC_ONLY
                          setContentDisplay(ContentDisplay.TEXT_ONLY);
                          //setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
  
                          setText(dateConverter.toString(item));
                          datePicker.setValue((LocalDate) item);
                          setGraphic(datePicker);
                      }
  
                  }
  
                  @Override
                  public void startEdit() {
  
                      super.startEdit();
  
                      if ( getGraphic() != null &amp;&amp; getGraphic() instanceof DatePicker ) {
                          //The problem only occurs when I set content display to TEXT_ONLY in updateItem().
                          setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
  
                          //If I requestFocus() on the graphic, the DatePicker gets the focus but I cannot edit the date
                          //by clicking in the editor and typing something in.
  
                          //If I do NOT requestFocus() on the graphic, the cell containing the DatePicker gets focus but
                          //I can then click in the DatePicker's editor and type something in.  However, I cannot just
                          //start typing as the DatePicker doesn't have focus.
  
                          //This happens irrespective of whether I double-click on a cell to start the edit or
                          //navigate to the cell via the keyboard and then hit F2.
  
                          //The behaviour only appears the first time I edit a DatePicker in a given row.
                          //The second and subsequent edits for the same row work fine.
  
                          getGraphic().requestFocus();
  
                          //Requesting focus on the DatePicker's editor doesn't appear to have any effect, either with or 
                          //without first requesting focus on the graphic.
                          ( (DatePicker) getGraphic() ).getEditor().requestFocus();
                          ( (DatePicker) getGraphic() ).getEditor().selectAll();
                      }
  
                  }
  
                  @Override
                  public void cancelEdit() {
                      super.cancelEdit();
                      setContentDisplay(ContentDisplay.TEXT_ONLY);
                  }
              };
  
              return cell;
  
          });
          //**************************************************************
  
          col2.setPrefWidth(120);
  
          col3.setCellValueFactory(cellData -&gt; cellData.getValue().field3Property());
          col3.setCellFactory(TextFieldTableCell.&lt;DataModel, String&gt;forTableColumn(new DefaultStringConverter()));
  
          tv.getColumns().addAll(Arrays.asList(col1, col2, col3));
  
      }
  
      private void loadDummyData() {
  
          ol.add(new DataModel("1", LocalDate.parse("2001-01-01"), "x"));
          ol.add(new DataModel("2", LocalDate.parse("2001-01-01"), "x"));
          ol.add(new DataModel("3", LocalDate.parse("2001-01-01"), "x"));
          ol.add(new DataModel("4", LocalDate.parse("2001-01-01"), "x"));
          ol.add(new DataModel("5", LocalDate.parse("2001-01-01"), "x"));
  
      }
  
      private class DataModel {
  
          private final StringProperty field1;
          private final ObjectProperty&lt;LocalDate&gt; field2;
          private final StringProperty field3;
  
          public DataModel(
              String field1,
              LocalDate field2,
              String field3
          ) {
              this.field1 = new SimpleStringProperty(field1);
              this.field2 = new SimpleObjectProperty&lt;&gt;(field2);
              this.field3 = new SimpleStringProperty(field3);
          }
  
          public String getField1() {return field1.get().trim();}
          public void setField1(String field1) {this.field1.set(field1);}
          public StringProperty field1Property() {return field1;}
  
          public LocalDate getField2() {return field2.get();}
          public void setField2(LocalDate field2) {this.field2.set(field2);}
          public ObjectProperty&lt;LocalDate&gt; field2Property() {return field2;}
  
          public String getField3() {return field3.get().trim();}
          public void setField3(String field3) {this.field3.set(field3);}
          public StringProperty field3Property() {return field3;}
  
      }
  
      @Override
      public void start(Stage stage) throws Exception {
          stage.setScene(new Scene(createContent()));
          stage.setTitle("OpenJFX11 - DatePicker in TableView");
          stage.setWidth(600D);
          stage.setHeight(600D);
          stage.show();
      }
  
      public static void main(String[] args) {
          launch(args);
      }
  
  }
  </code></pre>