Почему doAction() рано или поздно завершает работу?
У меня какая-то странная проблема. у меня есть doAction()
Качели с for
цикл для удаления строк из JTable
и база данных. Если for
петля велика done()
Метод сработает до завершения цикла, эффективно останавливая выполнение на полпути.
Мой код:
public void doAction() throws Exception {
int selectedRows[];
int modelRows[];
java.util.ArrayList<customRecord> condemned;
customTableModel dataSource;
boolean databaseDelete = false;
Object uniqueID;
int rowCount = 0;
dataSource = (customTableModel)table.getModel();
selectedRows = table.getSelectedRows();
condemned = new java.util.ArrayList<customRecord>();
modelRows = new int[selectedRows.length];
for(int i=0;i<selectedRows.length;i++)
modelRows[i] = table.convertRowIndexToModel(selectedRows[i]);
selectedRows = null;
for(int i= 0; i < modelRows.length; i++){
uniqueID = dataSource.getUniqueID(modelRows[i]);
System.out.println("Debug: spot 1, rowCount = " + rowCount + ", i = " + i + ", length = " + modelRows.length);
if(uniqueID == null)
dataSource.removeRow(modelRows[i]);
else if(adminPrivileges){
condemned.add(//Record being looked at);
databaseDelete = true;
System.out.println("Debug: spot 2, rowCount = " + rowCount + ", i = " + i);
dataSource.removeRow(modelRows[i]);
if(condemned.size() >= 100){
database.clearData(condemned);
condemned.clear();
}
System.out.println("Debug: spot 3, rowCount = " + rowCount + ", i = " + i);
}
System.out.println("Debug: spot 4, rowCount = " + rowCount + ", i = " + i + ", uniqueID = " + uniqueID.toString() + "\n");
if(++rowCount >= 1000){
System.out.println("rowCount = " + rowCount + ", in break");
break;
}
}
if(databaseDelete){
if(condemned.size() > 0)
database.clearData(condemned);
loadData(table,database,filterParams);
}
}
public void done() {
System.out.println("Debug: in done()");
table.setVisible(true);
//Display warning message if the number of rows reached the limit
if(rowCount >= 1000){
// Display Limit Reached Warning;
}
}
Мой вывод здесь выглядит так:
Debug: spot 1, rowCount = 0, i = 0, length 1006
Debug: spot 2, rowCount = 0, i = 0
Debug: spot 3, rowCount = 0, i = 0
Debug: spot 4, rowCount = 0, i = 0, uniqueID = 2608
.
.
.
Debug: spot 1, rowCount = 505, i = 505, length = 1006
Debug: spot 2, rowCount = 505, i = 505
Debug: spot 3, rowCount = 505, i = 505
Debug: spot 4, rowCount = 505, i = 505, uniqueID = 3073
Debug: spot 1, rowCount = 506, i = 506, length = 1006
Debug: in done()
Если большой for
цикл установлен, чтобы перейти от большого к маленькому, как for(i = modelRows.length-1; i >= 0; i--)
это будет немного дальше:
Debug: spot 1, rowCount = 0, i = 1005, length 1006
Debug: spot 2, rowCount = 0, i = 1005
Debug: spot 3, rowCount = 0, i = 1005
Debug: spot 4, rowCount = 0, i = 1005, uniqueID = 3073
.
.
.
Debug: spot 1, rowCount = 899, i = 106, length = 1006
Debug: spot 2, rowCount = 899, i = 106
Debug: spot 3, rowCount = 899, i = 106
Debug: spot 4, rowCount = 899, i = 106, uniqueID = 2174
Debug: in done()
Как я могу сделать / разрешить это doAction()
метод завершен правильно? Существует ли максимальное время, которое Swingworker выполнит до done()
метод называется?
РЕДАКТИРОВАТЬ
Я полагаю, что я запутался (и, вероятно, все остальные), говоря, что doAction()
это SwingWorker
, doAction()
это метод, который вызывается из doInBackground()
в классе, который расширяется SwingWorker
,
Код:
protected interface LengthyAction{
public customActions getAction();
public java.awt.Component getComponent();
public void doAction() throws Exception;
public void done();
}
private class DataSwingWorker extends javax.swing.SwingWorker{
private LengthyAction action;
public DataSwingWorker(LengthyAction targetAction){
action = targetAction;
setCursor(action.getComponent(),java.awt.Cursor.WAIT_CURSOR);
if(listener != null)
listener.actionPerformed(new java.awt.event.ActionEvent(**stuff**));
}
.
.
.
@Override
protected Object doInBackground() throws Exception {
action.doAction();
return null;
}
@Override
protected void done() {
if(listener != null)
listener.actionPerformed(new java.awt.event.ActionEvent(**stuff**));
action.done();
}
}
Я нашел ответ на свою проблему, и это действительно не имело ничего общего с моими первоначальными мыслями. Вынимая:
if(condemned.size() >= 100){
database.clearData(condemned);
condemned.clear();
}
В большой doAction()
цикл делает все работает. Кажется, что это приводило к тому, что уникальные идентификаторы пропускали 100 мест вперед, и я нажимал на конец массива до конца цикла, давая NullPointerException
,
Спасибо за всю помощь, в итоге она поставила меня на правильный путь.
1 ответ
Я постараюсь ответить на вопросы, которые пока кажутся ответственными, основываясь на опубликованных вами данных:
У меня есть doAction() Swingworker с циклом for для удаления строк из JTable и базы данных...... Нет, это метод doAction () для объекта, который вызывается из метода doInBackground().
Это не хорошо. Если вы звоните doAction()
изнутри вашего SwingWorker doInBackground()
метод, который означает, что ваш код грубо нарушает правила потоков Swing, делая вызовы Swing, особенно вызовы, которые изменяют состояние компонентов Swing, из фонового потока. На самом деле это может быть причиной или, по крайней мере, основной причиной ваших периодических проблем с запуском этого фонового потока.
Есть ли максимальное время, которое Swingworker выполнит до вызова метода done()?
Это называется, когда doInBackground()
Метод завершил свои действия и исключений не найдено. Ключевой вопрос: проверяете ли вы исключения, возникающие во время работы SwingWorker? Это будет проверено по телефону get()
на вашем SwingWorker в блоке try/catch и после того, как он завершит свои действия.
Как я могу сделать / позволить этот метод doAction () завершить правильно?
К сожалению, трудно сказать, основываясь на вашем текущем коде, так как мы не можем скомпилировать или запустить его. Если все еще застряли, создайте и опубликуйте свою минимальную примерную программу или SSCCE.
Мои основные рекомендации:
- Прежде всего, переписать весь этот код так, чтобы он строго следовал правилам потоков Swing. Это имеет наибольшие шансы для решения вашей проблемы. Поймите, что SwingWorkers автоматически разрешают поддержку PropertyChangeListener, и это может быть хорошим способом связи между фоновым потоком и потоком событий Swing.
- Затем убедитесь, что код реорганизован так, чтобы ваши классы были небольшими независимо тестируемыми модулями, а затем протестируйте каждый из них по максимуму, пытаясь заставить их потерпеть неудачу любым способом, о котором вы только можете подумать.