0

I´m trying to display a Map with a TableView, so far all works fine, but when I´m editing the value of any field, the change only is saved when and press ENTER key and I would like that the change was stored when the input field loses the focus.

I have tried to reach this behaviour with a custom render but It doesn´t work I have expected.

This is my code, and the only thing that I need is to know the way to save the changes when the user move the mouse and unselect the row, losing the focus.

import java.util.HashMap;
import java.util.Map;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;  
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.MapValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;

public class TableViewSample extends Application {

public static final String Column1MapKey = "Key";
public static final String Column2MapKey = "Value";

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

@Override
public void start(Stage stage) {
    Scene scene = new Scene(new Group());
    stage.setTitle("Table View Sample");
    stage.setWidth(300);
    stage.setHeight(500);

    TableColumn<Map, String> firstDataColumn = new TableColumn<>("Key");
    TableColumn<Map, String> secondDataColumn = new TableColumn<>("Value");

    firstDataColumn.setCellValueFactory(new MapValueFactory(Column1MapKey));
    firstDataColumn.setMinWidth(130);
    secondDataColumn.setCellValueFactory(new MapValueFactory(Column2MapKey));
    secondDataColumn.setMinWidth(130);

    TableView table_view = new TableView<>(generateDataInMap());

    table_view.setEditable(true);
    table_view.getSelectionModel().setCellSelectionEnabled(true);
    table_view.getColumns().setAll(firstDataColumn, secondDataColumn);
    Callback<TableColumn<Map, String>, TableCell<Map, String>>
        cellFactoryForMap = new Callback<TableColumn<Map, String>,
            TableCell<Map, String>>() {
                @Override
                public TableCell call(TableColumn p) {
                    return new TextFieldTableCell(new StringConverter() {
                        @Override
                        public String toString(Object t) {
                            return t.toString();
                        }
                        @Override
                        public Object fromString(String string) {
                            return string;
                        }                                    
                    });
                }
    };
    firstDataColumn.setCellFactory(cellFactoryForMap);
    secondDataColumn.setCellFactory(cellFactoryForMap);

    final VBox vbox = new VBox();

    vbox.setSpacing(5);
    vbox.setPadding(new Insets(10, 0, 0, 10));
    vbox.getChildren().addAll(table_view);

    ((Group) scene.getRoot()).getChildren().addAll(vbox);

    stage.setScene(scene);

    stage.show();
}

private ObservableList<Map> generateDataInMap() {
    int max = 10;
    ObservableList<Map> allData = FXCollections.observableArrayList();
    for (int i = 1; i < max; i++) {
        Map<String, String> dataRow = new HashMap<>();

        String key = "Key " + i;
        String value = "Value " + i;

        dataRow.put(Column1MapKey, key);
        dataRow.put(Column2MapKey, value);

        allData.add(dataRow);
    }
    return allData;
}
}

Regards

vcima
  • 421
  • 1
  • 7
  • 20
  • Possible duplicate of [*TableView doesn't commit values on focus lost event*](https://stackoverflow.com/q/29576577/230513). – trashgod Jun 10 '17 at 20:26

1 Answers1

0

You might be able to get there adding an event listener on table_view.focusedProperty.

This would listen to the focus of the table view though, and not to the focus for each item.

table_view.focusedProperty.addListener( new ChangeListener<Boolean>(){
FocusPropertyChangeListener() { System.out.println("New FPCL instance"); }

    @Override
    public void changed(ObservableValue<? extends Boolean> ov, 
        Boolean oldb, Boolean newb) {
        System.out.println("Focus change triggered");
    }



    });
Vinagy
  • 133
  • 2
  • 11