title: JavaFX Table Cell Editing
body: <p>I am trying to make a program in Java to manage my bookie accounts. I'm new to java, so I thought I would chose something simple to see how things work. I decided to use a tableview and make the individual cells editable. I've been following this tutorial <a href="http://java-buddy.blogspot.co.uk/2012/04/javafx-2-editable-tableview.html" rel="noreferrer">http://java-buddy.blogspot.co.uk/2012/04/javafx-2-editable-tableview.html</a>. It details how to do it using java code, and copying that into a new class works perfectly. I decided to try and tweak it to work with FXML, since I like Sceneviewer. My issue is, data is loaded in to the table, but when I click/doubleclick a cell, nothing happens. Here's my code.</p>
  
  <p>testController.java</p>
  
  <pre><code>import javafx.collections.FXCollections;
  import javafx.collections.ObservableList;
  import javafx.event.EventHandler;
  import javafx.fxml.FXML;
  import javafx.fxml.Initializable;
  import javafx.scene.control.*;
  import javafx.scene.control.cell.PropertyValueFactory;
  import javafx.scene.input.KeyCode;
  import javafx.scene.input.KeyEvent;
  import javafx.util.Callback;
  
  import java.net.URL;
  import java.util.ResourceBundle;
  
  public class testController implements Initializable {
  
  @FXML
  private TableColumn&lt;Account, String&gt; usernameCol;
  
  @FXML
  private TableColumn&lt;Account, String&gt; balanceCol;
  
  @FXML
  private TableView&lt;Account&gt; accountTable;
  
  @FXML
  private TableColumn&lt;Account, String&gt; bookieCol;
  
  @FXML
  private TableColumn&lt;Account, String&gt; passwordCol;
  
  private ObservableList&lt;Account&gt; dataList =
          FXCollections.observableArrayList(
                  new Account("bookie", "username", "password", "0"));
  
  
  @Override
  public void initialize(URL location, ResourceBundle resources) {
      Callback&lt;TableColumn, TableCell&gt; cellFactory =
              new Callback&lt;TableColumn, TableCell&gt;() {
                  public TableCell call(TableColumn p) {
                      return new EditingCell();
                  }
              };
  
      bookieCol.setCellValueFactory(
              new PropertyValueFactory&lt;&gt;("fieldBookie"));
  
      usernameCol.setCellValueFactory(
              new PropertyValueFactory&lt;&gt;("fieldUsername"));
  
      usernameCol.setOnEditCommit(
              new EventHandler&lt;TableColumn.CellEditEvent&lt;Account, String&gt;&gt;() {
                  @Override public void handle(TableColumn.CellEditEvent&lt;Account, String&gt; t) {
                      ((Account)t.getTableView().getItems().get(
                              t.getTablePosition().getRow())).setFieldUsername(t.getNewValue());
                  }
              });
  
      passwordCol.setCellValueFactory(
              new PropertyValueFactory&lt;Account, String&gt;("fieldPassword"));
  
      balanceCol.setCellValueFactory(
              new PropertyValueFactory&lt;Account, String&gt;("fieldBalance"));
  
      accountTable.setItems(dataList);
  
  }
  
  class EditingCell extends TableCell&lt;Account, String&gt; {
  
      private TextField textField;
  
      public EditingCell() {
      }
  
      @Override
      public void startEdit() {
          super.startEdit();
  
          if (textField == null) {
              createTextField();
          }
  
          setGraphic(textField);
          setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
          textField.selectAll();
      }
  
      @Override
      public void cancelEdit() {
          super.cancelEdit();
  
          setText(String.valueOf(getItem()));
          setContentDisplay(ContentDisplay.TEXT_ONLY);
      }
  
      @Override
      public void updateItem(String item, boolean empty) {
          super.updateItem(item, empty);
  
          if (empty) {
              setText(null);
              setGraphic(textField);
          } else {
              if (isEditing()) {
                  if (textField != null) {
                      textField.setText(getString());
                  }
                  setGraphic(textField);
                  setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
              } else {
                  setText(getString());
                  setContentDisplay(ContentDisplay.TEXT_ONLY);
              }
          }
      }
  
      private void createTextField() {
          textField = new TextField(getString());
          textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
          textField.setOnKeyPressed(t -&gt; {
              if (t.getCode() == KeyCode.ENTER) {
                  commitEdit(textField.getText());
              } else if (t.getCode() == KeyCode.ESCAPE) {
                  cancelEdit();
              }
          });
      }
  
      private String getString() {
          return getItem() == null ? "" : getItem();
      }
  }
  }
  </code></pre>
  
  <p>And here is my Account.java file.</p>
  
  <pre><code>import javafx.beans.property.SimpleStringProperty;
  
  
  public class Account {
      private SimpleStringProperty fieldBookie;
      private SimpleStringProperty fieldUsername;
      private SimpleStringProperty fieldPassword;
      private SimpleStringProperty fieldBalance;
  
      Account(String fbookie, String fusername, String fpassword, String fbalance){
          this.fieldBookie = new SimpleStringProperty(fbookie);
          this.fieldUsername = new SimpleStringProperty(fusername);
          this.fieldPassword = new SimpleStringProperty(fpassword);
          this.fieldBalance = new SimpleStringProperty(fbalance);
      }
  
      public String getFieldBookie() {
          return fieldBookie.get();
      }
  
      public String getFieldUsername() {
          return fieldUsername.get();
      }
  
      public String getFieldPassword() {
          return fieldPassword.get();
      }
  
      public String getFieldBalance() {
          return fieldBalance.get();
      }
  
      public void setFieldBookie(String fBookie) {
          fieldBookie.set(fBookie);
      }
  
      public void setFieldUsername(String fUsername) {
          fieldUsername.set(fUsername);
      }
  
      public void setFieldPassword(String fPassword) {
          fieldUsername.set(fPassword);
      }
  
      public void setFieldBalance(String fBalance) {
          fieldUsername.set(fBalance);
      }
  
  }
  </code></pre>
  
  <p>Lastly, here is my fxml file.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;?import javafx.scene.control.*?&gt;
  &lt;?import javafx.scene.canvas.*?&gt;
  &lt;?import java.lang.*?&gt;
  &lt;?import javafx.scene.*?&gt;
  
  &lt;Group xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testController"&gt;
     &lt;children&gt;
        &lt;TableView fx:id="accountTable" editable="true" prefHeight="291.0" prefWidth="302.0"&gt;
          &lt;columns&gt;
            &lt;TableColumn fx:id="bookieCol" prefWidth="75.0" text="Bookie" /&gt;
            &lt;TableColumn fx:id="usernameCol" prefWidth="75.0" text="Username" /&gt;
              &lt;TableColumn fx:id="passwordCol" prefWidth="75.0" text="Password" /&gt;
              &lt;TableColumn fx:id="balanceCol" prefWidth="75.0" text="Balance" /&gt;
          &lt;/columns&gt;
        &lt;/TableView&gt;
     &lt;/children&gt;
  &lt;/Group&gt;
  </code></pre>
  
  <p>As I said earlier, nothing happens when I click on the Username cell. No errors, no textfield, just nothing. 
  Any help would be greatly appreciated! Thanks</p>