Как регистрировать изменения в textfield который находится в tablecolumn > tableview?

У меня есть таблица в которой есть textField я хочу отслеживать изменение в этом textField, с помощью KeyEvent. Main Class:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle(" ");
        primaryStage.setScene(new Scene(root));
        primaryStage.initStyle(StageStyle.DECORATED);
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

Controller Class:

package sample;

import java.net.URL;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.Random;
import java.util.ResourceBundle;

import javafx.beans.Observable;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;

public class Controller {
    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;
    @FXML
    private TableView<converted> table1;
    
    
    
    @FXML
    void initialize () throws NoSuchFieldException {
        ObservableList<converted> Strings = FXCollections.observableArrayList();
        Strings.add(new converted("Один", ""));
        Strings.add(new converted("Два", ""));
        Strings.add(new converted("Три", ""));
        
        
        
        TableColumn<converted, String> convertedStringTableColumn = new TableColumn<>("column");
        convertedStringTableColumn.setMinWidth(200);
        convertedStringTableColumn.setCellValueFactory(new PropertyValueFactory<>("string"));
        table1.setItems(Strings);
        table1.getColumns().addAll(convertedStringTableColumn);

        TableColumn<converted, String> convertedStringTableColumn1 = new TableColumn<>("field");
        convertedStringTableColumn1.setMinWidth(100);
        convertedStringTableColumn1.setCellValueFactory(new PropertyValueFactory<>("field"));
        table1.getColumns().addAll(convertedStringTableColumn1);
    }
}
    

Table Class:

package sample;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.control.TextField;

public class converted {
    private SimpleStringProperty string;
    private TextField field;

    public converted(String sstring, String field) {
        this.string = new SimpleStringProperty(sstring);
        this.field = new TextField(field);
    }

    public TextField getField() {
        return field;
    }

    public void setField(TextField field) {
        this.field = field;
    }

    public void setString(String sstring){
        this.string.set(sstring);
    }

    public String getString (){
        return  string.get();
    }
}

FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="352.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
  <children>
    <TableView fx:id="table1" layoutX="23.0" layoutY="100.0" prefHeight="285.0" prefWidth="306.0" />
  </children>   
</AnchorPane>


Ответы (1 шт):

Автор решения: Алексей Босак

Задай в качестве cellFactory ячейку, в которой будет нужный тебе компонент. А то что ты делаешь сейчас в классе converted неправильно. Это ведь модель данных, в которой, грубо говоря, хранятся сами данные для ячеек. Чтобы все заработало удали из converted TextField и оставь вместо него SimpleStringProperty. P.S. Именуй классы с большой буквы, а то converted сбивает с толку :) В данном случае пример с TextField:

TableColumn<converted, String> col = new TableColumn<>();
col.setCellFactory(c -> {
 return new CustomCell();
});

И сама ячейка:

public class CustomCell extends TableCell<String> {
  private TextField textField;
  public CustomCell() {
    textField = new TextField();
    // где-нибудь тут можешь повесить обработчики
    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
  }

  @Override
  protected void updateItem(String o, boolean empty) {
    super.updateItem(o, empty);

    if(empty) {
      setGraphic(null); //удалит TextField если нету графики 
    } else {
      setGraphic(textField); 
      textField.setText(o); //нужно чтобы данные обновлялись при скроллинге. С этой штукой нужно быть внимательнее, при неправильном обращении может затереть текст, который ты вводил
    }
  }
}
→ Ссылка