Как сделать проверку, прежде чем разрешить редактирование данной строки в JTable
Вопрос
Проблема довольно проста. У меня есть JTable, показывающий кэшированные данные из базы данных. Если пользователь щелкает ячейку для редактирования, я хочу попытаться заблокировать эту строку в базе данных. Если блокировка не удалась, я хочу запретить редактирование.
Но, похоже, я не могу найти какой-либо чистый способ сделать это. Я что-то упустил?
Решение
Поскольку вам нужно тестировать на клике, вы не можете использовать способ модели, поэтому вам следует попробовать переопределить public void changeSelection (int rowIndex, int columnIndex, логическое переключение, расширение oolean) . Если строка заблокирована, не вызывайте super.changeSelection, и она должна оставить строку невыбранной.
Другие советы
Перед редактированием / установкой значения модель таблицы запрашивает через TableModel.isCellEditable (row, col), является ли эта ячейка редактируемой. Здесь вы можете реализовать свой замок. и после TableModel.setValue (row, col, val) вы должны разблокировать это. НО. Операция блокировки должна занять много времени и сделать ваш пользовательский интерфейс не ответственным. И это плохо. Попробуйте другой подход. Что насчет ленивого провала? Вы блокируете строку, проверяете достоверность данных и терпите неудачу, если данные новее. Если данные в порядке, вы кладете их вниз. ОТКРЫТЬ.
У Oracle есть хороший способ справиться с этим, но я не знаю, насколько это универсально применимо.
В Oracle вы можете использовать FOR UPDATE в операторе SELECT, чтобы заблокировать запись во время ее чтения.
Например, если вы выбираете строку для отображения:
select * into v_row from my_table where my_table_id = 1
for update;
Это позволит читать, но предотвращать обновления. Если у другой транзакции есть блокировка, ваша транзакция будет ждать, пока она не станет доступной (или время ожидания истечет). Если вы хотите, чтобы оператор генерировал исключение, если вы пытаетесь заблокировать, добавьте NOWAIT .
select * into v_row from my_table where my_table_id = 1
for update nowait;
Если строка уже заблокирована, вы получите:
ORA-00054: resource busy and acquire with NOWAIT specified.
Надеюсь, это поможет.
Вместо этого вы можете подождать, пока пользователь действительно что-то изменит, а затем переопределить JTable.editingStopped, чтобы выполнить работу там (вы даже можете проверить, изменилось ли значение)
Таким образом, блокировка не выполняется до тех пор, пока пользователь не изменит что-либо.