/* * This file is a part of GrantMaster. * Copyright (C) 2015 Gábor Fehér <feherga@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.github.gaborfeher.grantmaster.framework.ui.cells; import com.github.gaborfeher.grantmaster.framework.base.EditableTableRowItem; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.EventHandler; import javafx.scene.control.Alert; import javafx.scene.control.TableCell; import javafx.scene.control.TextField; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; public class TextFieldTableCell<S extends EditableTableRowItem, T> extends TableCell<S, T> { final String property; final TextField editTextField; final MultiStringConverter<T> stringConverter; final Class<T> valueType; // true if the last editing session was cancelled by user (currently esc key) // This disables later spurious commit messages. boolean userCancelled; public TextFieldTableCell( String property, MultiStringConverter<T> stringConverter0, Class<T> valueType) { this.property = property; this.stringConverter = stringConverter0; this.valueType = valueType; editTextField = new TextField(); editTextField.setOnKeyPressed(new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { if (event.getCode().equals(KeyCode.ENTER)) { parseAndCommit(editTextField.getText()); } else if (event.getCode().equals(KeyCode.ESCAPE)) { userCancelled = true; cancelEdit(); } } }); editTextField.focusedProperty().addListener( new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> ov, Boolean t1, Boolean t2) { if (!t2 && t1) { parseAndCommit(editTextField.getText()); } } } ); } private EditableTableRowItem getEntityWrapper() { return (EditableTableRowItem) getTableRow().getItem(); } private void parseAndCommit(String val) { if (userCancelled) { return; // User cancel was before this commit message, ignore this. } if (val == null) { return; } T parsed = stringConverter.fromString(val); if (parsed != null) { commitEdit(parsed); } else { userCancelled = true; cancelEdit(); Alert alert = new Alert(Alert.AlertType.ERROR); alert.setHeaderText(stringConverter.getParseError()); alert.showAndWait(); } } @Override public void commitEdit(T val) { if (userCancelled) { return; // User cancel was before this commit message, ignore this. } if (getEntityWrapper().commitEdit(property, val, valueType)) { super.commitEdit(val); updateItem(val, false); } else { userCancelled = true; cancelEdit(); } } @Override public void startEdit() { userCancelled = false; if (getEntityWrapper() != null && getEntityWrapper().canEdit()) { super.startEdit(); updateItem(getItem(), false); editTextField.requestFocus(); } } @Override public void cancelEdit() { super.cancelEdit(); updateItem(getItem(), false); } @Override public void updateItem(final T item, final boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); setGraphic(null); } else { if (isEditing()) { editTextField.setText(stringConverter.toEditableString(item)); setGraphic(editTextField); setText(null); } else { setGraphic(null); setText(stringConverter.toString(item)); } } } }