Как сделать проверку, прежде чем разрешать редактирование данной строки в JTable

Проблема вполне элементарная. У меня есть JTable, показывающий кэшированные данные из базы данных. Если пользователь щелкает ячейку для редактирования, я хочу попытаться заблокировать эту строку в базе данных. Если блокировка не удастся, я хочу предотвратить редактирование.

Но я не могу найти никакого чистого способа сделать это. Я что-то упускаю?


person Fuzzy76    schedule 29.10.2008    source источник


Ответы (4)


Поскольку вам нужно протестировать клик, вы не можете использовать способ модели сделать это, поэтому вам следует попробовать переопределить JTable public void changeSelection(int rowIndex, int columnIndex, логическое переключение, логическое расширение). Если строка заблокирована, не вызывайте super.changeSelection, и она должна оставить строку невыбранной.

person carson    schedule 29.10.2008
comment
На самом деле, я бы по-прежнему хотел, чтобы строки можно было выбирать (поскольку у меня есть функция для экспорта выбранных строк, которая не требует блокировки), но ваш ответ дал мне правильную идею. :) Вместо этого я переопределяю editCellAt() в JTable, а в остальном делаю так, как вы рекомендовали. - person Fuzzy76; 29.10.2008
comment
выбор ячейки и редактируемость не связаны. В упомянутом методе isTableCellEditable можно вернуть false и JTable не начнет редактирование. Но держать блокировку на строке до редактирования, как уже упоминалось, не очень хорошая идея. - person Peter; 29.10.2008

Перед редактированием/настройкой значения у модели таблицы через TableModel.isCellEditable(row,col) запрашивается, доступна ли для редактирования эта ячейка. Здесь вы можете реализовать свой замок. и после TableModel.setValue(row,col,val) вы должны разблокировать это. НО. Операция блокировки должна занять много времени и сделать ваш пользовательский интерфейс безответственным. И это ПЛОХО. Попробуйте другой подход. А как насчет ленивых неудач? Вы блокируете строку, проверяете достоверность данных и терпите неудачу, если данные новее. Если данные в порядке, вы записываете их. РАЗБЛОКИРОВАТЬ.

person Rastislav Komara    schedule 29.10.2008

У 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.

Надеюсь, это поможет.

person Nick Pierpoint    schedule 29.10.2008

Вместо этого вы можете подождать, пока пользователь действительно что-то изменит, а затем переопределить JTable.editingStopped, чтобы выполнить работу там (вы даже можете проверить, изменилось ли значение)

Таким образом, блокировка не выполняется до тех пор, пока пользователь действительно что-то не изменит.

person John Gardner    schedule 29.10.2008