Редактирование
При редактировании обработчик onEditCommit
уведомляется, когда редактирование было совершено (что неудивительно).Этот обработчик отвечает за запись нового значения в модель (в вашем случае, Person
).Когда это происходит, TableView
автоматически обновляется для отображения нового значения.
Ваше решение установить текст Cell
равным значению TextField
при отмене редактирования не будет работать,В конце концов, когда обновление каким-либо образом инициируется, Cell
обновится, чтобы отобразить реальные данные, предоставленные моделью (полученные cellValueFactory
).Кроме того, вы фактически не обновляли модель, и поэтому предполагаемое редактирование - это просто визуальная вещь.
Об учебнике
Учебник , на который вы ссылаетесьимеет проблемы.Самым большим из них является то, что предполагается, что когда TextField
теряет фокус, вы можете успешно зафиксировать новое значение.Как вы испытываете, это не так.Вы можете увидеть, что многие другие столкнулись с этой проблемой, взглянув на этот вопрос: TableView не фиксирует значения для события потери фокуса .Ответы на этот вопрос предоставляют множество способов взломать вокруг проблемы.Некоторые также указывают на сообщения об ошибках, указывающие на то, что поведение no-commit-on-lost-focus на самом деле непреднамеренно;однако эти ошибки не были исправлены в JavaFX 11.0.2.
Это означает, что:
textField.focusedProperty().addListener(
(ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2) -> {
if (!arg2) {
commitEdit(textField.getText());
}
});
Не будет когда-либо фиксировать редактирование.Вы (но на самом деле учебник) не предоставляете никаких рабочих средств для фиксации нового значения, потому что редактирование отменяется ко времени, когда вызывается if (!arg2) { commitEdit(...); }
.Поскольку редактирование отменено, событие коммита редактирования не сработало, и ваш TableColumn
не может записать новое значение в элемент модели.Что вы можете сделать, хотя это не решит проблему «без фиксации при потере фокуса», это добавить обработчик onAction
к вашему TextField
, который фиксирует редактирование.Вы, вероятно, захотите предоставить средство для отмены редактирования с помощью клавиатуры.Это будет выглядеть примерно так:
textField.setOnAction(event -> {
commitEdit(textField.getText());
event.consume();
}
textField.setOnKeyPressed(event -> {
if (event.getCode() == KeyCode.ESCAPE) {
cancelEdit();
event.consume();
}
}
Это будет зафиксировать редактирование при нажатии клавиши Enter и отменит редактирование при нажатии клавиши Esc .
Обратите внимание, что TextFieldTableCell
уже обеспечивает это поведение из коробки, нет необходимости развертывать собственную реализацию EditCell
.Однако, если вы хотите зафиксировать редактирование при потере фокуса, вам нужно будет посмотреть ответы на TableView не фиксирует значения для события фокуса потерянного (или его связанных / связанных вопросов) ипопытайтесь использовать одно из указанных решений (хаков).
Кроме того, как отмечено в приведенной ниже документации, вам не нужно предоставлять собственный обработчик onEditCommit
, чтобы записать новое значение в модель.- TableColumn
делает это по умолчанию (при условии, что cellValueFactory
возвращает WritableValue
).
Документация
Возможно чтение документации TableView
будет более полезным, чем учебное пособие, которое вы читаете, или, по крайней мере, будет дополнять его:
Редактирование
Этот элемент управления поддерживает встроенное редактирование значений, иВ этом разделе делается попытка дать обзор доступных API и способов их использования.
Во-первых, для редактирования ячеек чаще всего требуется другой пользовательский интерфейс, чем когда ячейка не редактируется.Это ответственность используемой реализации Cell
.Для TableView
настоятельно рекомендуется, чтобы редактирование выполнялось по-1075 *, а не по строке, поскольку чаще всего вы хотите, чтобы пользователи редактировали каждое значение столбца по-разному, и этот подход позволяет использовать редакторы, специфичные для каждого столбца.Вы можете выбрать, находится ли ячейка постоянно в состоянии редактирования (например, это характерно для CheckBox
ячеек), или переключиться на другой пользовательский интерфейс, когда начинается редактирование (например, при получении двойного щелчка по ячейке).
Чтобы узнать, когда для ячейки было запрошено редактирование, просто переопределите метод Cell.startEdit()
и обновите текст и графические свойства ячейки соответствующим образом (например, установите для текста значение null и установите для графики значение TextField
),Кроме того, вы также должны переопределить Cell.cancelEdit()
, чтобы вернуть пользовательский интерфейс в исходное визуальное состояние после завершения редактирования.В обоих случаях важно также убедиться, что вы вызываете метод super
, чтобы ячейка выполняла все обязанности, которые она должна выполнять для входа или выхода из режима редактирования.
Как только ваша ячейка находится в состоянии редактированияСледующее, что вас, скорее всего, заинтересует, это как зафиксировать или отменить происходящее редактирование.Это ваша ответственность как поставщика клеточной фабрики.Ваша реализация ячейки будет знать, когда редактирование закончится, на основе пользовательского ввода (например, когда пользователь нажимает клавиши Enter или ESC на своей клавиатуре).Когда это происходит, вы обязаны позвонить Cell.commitEdit(Object)
или Cell.cancelEdit()
, в зависимости от ситуации.
Когда вы звоните Cell.commitEdit(Object)
, событие вызывается на TableView
, что можно наблюдать, добавивEventHandler
через TableColumn.setOnEditCommit(javafx.event.EventHandler)
.Точно так же вы можете наблюдать события редактирования для начала редактирования и отмены редактирования.
По умолчанию обработчик фиксации редактирования TableColumn
не равен нулю, с обработчиком по умолчанию, который пытается перезаписать значение свойства для элемента втекущая редактируемая строка.Это можно сделать, когда метод Cell.commitEdit(Object)
передается в новом значении, и он передается обработчику фиксации редактирования через запускаемый CellEditEvent
.Это просто вопрос вызова TableColumn.CellEditEvent.getNewValue()
для получения этого значения.
Очень важно отметить, что если вы вызовете TableColumn.setOnEditCommit(javafx.event.EventHandler)
со своим собственным EventHandler
, то вы удалите обработчик по умолчанию.Если вы не обработаете обратную запись в свойство (или соответствующий источник данных), ничего не произойдет.Вы можете обойти это, используя метод TableColumnBase.addEventHandler(javafx.event.EventType, javafx.event.EventHandler)
, чтобы добавить TableColumn.editCommitEvent()
EventType
с желаемым EventHandler
в качестве второго аргумента.Используя этот метод, вы не замените реализацию по умолчанию, но вы будете уведомлены, когда произошла фиксация редактирования.