JavaFX tab through editable cells

javafxlistenertableview

I have defined my own editable cell for a TableView. Everything works great but I want to be able to tab through the cells. Say I'm in cell [2,2] on a tab press I want the selected cell to go to [3,2]. Is this possible? How should I go about achieving this? Should I add a listener to the TableCell or the TableColumn?

Here is my custom TableCell

class EditingCell extends TableCell<Student, String> {

   private TextField textField;

   public EditingCell(Assignment assign) {
       this.setTooltip(new Tooltip(assign.getMaxPoints() + " pts max"));
   }

   @Override
   public void startEdit() {
       if (!isEmpty()) {
           super.startEdit();
           createTextField();
           setText(null);
           setGraphic(textField);
           textField.selectAll();
       }
   }

   @Override
   public void cancelEdit() {
       super.cancelEdit();

       setText((String) getItem());
       setGraphic(null);
   }

   @Override
   public void updateItem(String item, boolean empty) {
       super.updateItem(item, empty);

       if (empty) {
           setText(null);
           setGraphic(null);
       } else {
           if (isEditing()) {
               if (textField != null) {
                   textField.setText(getString());
               }
               setText(null);
               setGraphic(textField);
           } else {
               setText(getString());
               setGraphic(null);
           }
       }
   }

   private void createTextField() {
       textField = new TextField(getString());
       textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
       textField.focusedProperty().addListener(new ChangeListener<Boolean>(){
           @Override
           public void changed(ObservableValue<? extends Boolean> arg0, 
               Boolean arg1, Boolean arg2) {
                   if (!arg2) {
                       commitEdit(textField.getText());
                   }
           }
       });
   }

   private String getString() {
       return getItem() == null ? "" : getItem().toString();
   }

}

Best Answer

You can achieve this by adding a KeyListener to your textField. Try adding the following code to your createTextField()

textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
   @Override
   public void handle(KeyEvent t) {
       if (t.getCode() == KeyCode.ENTER) {
           commitEdit(Integer.parseInt(textField.getText()));
       } else if (t.getCode() == KeyCode.ESCAPE) {
           cancelEdit();
       } else if (t.getCode() == KeyCode.TAB) {
           commitEdit(Integer.parseInt(textField.getText()));
           TableColumn nextColumn = getNextColumn(!t.isShiftDown());
           if (nextColumn != null) {
               getTableView().edit(getTableRow().getIndex(), nextColumn);
           }
       }
   }
});

There are a few more things that you will have to take care of. For a complete example, please follow

https://gist.github.com/abhinayagarwal/9383881

Related Topic