title: JavaFX: Adding Click Listener to identify which cell was clicked in TableView
body: <p>I am trying to add a Click Listener/MouseEvent that can identify which cell in my TableView was clicked. I populate my TableView Columns with Strings. Currently all the solutions I have looked for get the whole row of the TableView, but I want to be able to select just one cell and do something with that data. I would also need to get the row and column of the clicked cell so that I can map it to my local data arraylist. So in summary:
  (1) Listener that can identify which cell was clicked
  (2) Get Row and Col of clicked cell</p>
  
  <p>This is my Controller for the class with the TableView currently:</p>
  
  <pre><code>public class BookingsUIController {
  
      @FXML
      private ResourceBundle resources;
  
      @FXML
      private URL location;
  
      @FXML
      private MenuButton monthMenuButton;
  
      @FXML
      private Button updateTableButton;
  
      @FXML
      private MenuButton dateMenuButton;
  
      @FXML
      private Button submitBookingsButton;
  
      @FXML
      private TableView&lt;Object&gt; tableView;
  
      private int currentMonth;
      private int currentDate;
  
      @FXML
      void updateTableButtonClicked(ActionEvent event) {
          updateTableButton.setDisable(true);
          Calendar calendar = Calendar.getInstance();
          calendar.set(Calendar.MONTH, currentMonth);
          calendar.set(Calendar.DATE, currentDate);
  
          boolean dateChanged = Runner.changeDate(calendar);
  
          if(dateChanged) {
              //UPDATECELLS
  
              try {
                  Main.showLoadingAlertLayout();
                  //SHOW ALERT LOADING DIALOG FOR 2 SECs
                  Thread.sleep(2000);
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
  
              Main.dismissLoadingAlertLayout();
              Runner.updateCellsWithAvailability();
  
              populateTable();
          }
          else {
              //SHOW FAIL DIALOG
          }
  
          updateTableButton.setDisable(false);
      }
  
      @FXML
      void submitBookingsClicked(ActionEvent event) {
  
      }
  
      @FXML
      void initialize() {
          assert monthMenuButton != null : "fx:id=\"monthMenuButton\" was not injected: check your FXML file 'BookingsUIFXML.fxml'.";
          assert updateTableButton != null : "fx:id=\"updateTableButton\" was not injected: check your FXML file 'BookingsUIFXML.fxml'.";
          assert dateMenuButton != null : "fx:id=\"dateMenuButton\" was not injected: check your FXML file 'BookingsUIFXML.fxml'.";
          assert submitBookingsButton != null : "fx:id=\"submitBookingsButton\" was not injected: check your FXML file 'BookingsUIFXML.fxml'.";
  
          Calendar cal = Calendar.getInstance();
          currentMonth = cal.get(Calendar.MONTH);
          currentDate = cal.get(Calendar.DATE);
          populateMenus();
          initTable();
          populateTable();
      }
  
      void populateMenus() {
          String[] months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
          for(int k = 0; k &lt; months.length; k++) {
              MenuItem item = new MenuItem(months[k]);
              item.setId(k+"");
              item.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
  
                  @Override
                  public void handle(ActionEvent event) {
                      monthMenuButton.setText(item.getText());
                      currentMonth = Integer.parseInt(item.getId());
  
                  }
              });
              monthMenuButton.getItems().add(item);
          }
  
          for(int i = 1; i &lt;= 31; i++) {
              MenuItem item = new MenuItem(i + "");
              item.setId(i + "");
              item.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
  
                  @Override
                  public void handle(ActionEvent event) {
                      dateMenuButton.setText(item.getText());
                      currentDate = Integer.parseInt(item.getId());
                  }
              });
              dateMenuButton.getItems().add(item);
          }
  
  
      }
  
      void initTable() {
  
          tableView.skinProperty().addListener((obs, oldSkin, newSkin) -&gt; {
              final TableHeaderRow header = (TableHeaderRow) tableView.lookup("TableHeaderRow");
              header.reorderingProperty().addListener((o, oldVal, newVal) -&gt; header.setReordering(false));
          });
  
          tableView.setOnMouseReleased(new EventHandler&lt;MouseEvent&gt;() {
  
              @Override
              public void handle(MouseEvent event) {
  //              // TODO Auto-generated method stub
  //              
  //              if(event.getButton().equals(MouseButton.PRIMARY)) {
  //                  
  //                  tableView.getSelectionModel().;
  //                  TableCell&lt;Object, String&gt; cell = (TableCell&lt;Object, String&gt;)event.getSource();
  //                  System.out.println("CLICKED: " + cell.getItem());
  //              }
  
              }
          });
  
  
  
          TableColumn&lt;Object, String&gt; roomsCol = new TableColumn&lt;Object, String&gt;("");
  //      roomsCol.setCellValueFactory(new Callback&lt;TableColumn.CellDataFeatures&lt;Object,String&gt;, ObservableValue&lt;String&gt;&gt;() {
  //
  //          @Override
  //          public ObservableValue&lt;String&gt; call(CellDataFeatures&lt;Object, String&gt; param) {
  //              // TODO Auto-generated method stub
  //              return new ReadOnlyObjectWrapper&lt;String&gt;((String)param.getValue());
  //          }
  //      });
  
          roomsCol.setCellValueFactory(createCellValueCallback(0));
          roomsCol.setSortable(false);
          tableView.getColumns().add(roomsCol);
  
  
  //      for(String room : Runner.rooms) {
  //          tableView.getItems().add(room);
  //      }
  //      
  
          for(int i = 0; i &lt; (Runner.times).size(); i++) {
              String time = Runner.times.get(i);
              final int index = i;
              TableColumn&lt;Object, String&gt; timesCol = new TableColumn&lt;Object, String&gt;(time);
              timesCol.setCellValueFactory(createCellValueCallback(i + 1));
              timesCol.setSortable(false);
  
              tableView.getColumns().add(timesCol);
  //          tableView.getColumns().add(new TableColumn&lt;ObservableList&lt;Cell&gt;, String&gt;(time));
          }
  
  
      }
  
      void emptyTable() {
  //      for(int i = 0; i &lt; tableView.getItems().size(); i++) {
  //          tableView.getItems().set(i, "");
  //      }
          tableView.getItems().clear();
      }
  
      void populateTable() {
          emptyTable();
          for(ArrayList&lt;Cell&gt; cells : Runner.cellsByRows) {
              ObservableList&lt;String&gt; stringList = FXCollections.observableArrayList();
              stringList.add(cells.get(0).getRoom());
              for(int i = 0; i &lt; cells.size(); i++) {
                  String show = "";
                  if(cells.get(i).isAvailable()) {
                      show = "OPEN";
                  }
                  else {
                      show = "X";
                  }
                  stringList.add(show);
              }
              tableView.getItems().add(stringList);
  
          }
  
          Runner.displayCells();
  
      }
  
      Callback&lt;TableColumn.CellDataFeatures&lt;Object,String&gt;, ObservableValue&lt;String&gt;&gt; createCellValueCallback(int i){
          final int index  = i;
          return new Callback&lt;TableColumn.CellDataFeatures&lt;Object,String&gt;, ObservableValue&lt;String&gt;&gt;() {
  
              @Override
              public ObservableValue&lt;String&gt; call(CellDataFeatures&lt;Object, String&gt; param) {
                  // TODO Auto-generated method stub
                  return new ReadOnlyObjectWrapper&lt;String&gt;(((ObservableList&lt;String&gt;)param.getValue()).get(index));
              }
          };
      }
  
  }
  </code></pre>
  
  <p>Any Help is Appreciated. Please let me know if I can provide any more info!</p>
  
  <p>Thanks in advance</p>