invokeLater странный вызов, после других методов
Я сталкиваюсь с очень раздражающей проблемой. Я разрабатываю библиотечную программу, и когда я выполняю заданные последовательные действия, я добавляю неожиданный ряд в JTable моих книг.
Действия таковы:
- запуск программы
- добавить фильтр на основе комментариев (у меня есть много фильтров, которые являются классами, унаследованными от RowFilter, все они связаны с RowSorter JTable. Эта часть программы работает отлично). В исходном состоянии есть две книги в JTable, которые являются "le livre de la jungle" и "Eloge des mathématiques". После использования фильтра остается только один "Eloge des mathématiques". Другой не отображается, но все еще находится в модели.
- выберите в JTable оставшуюся книгу ("Жизнь в джунглях"). С помощью отладчика я увидел, что во время действий, вызываемых этим щелчком, создается книга с пустым названием и автором. Это не видно, но если я
- деактивируйте все фильтры, теперь в JTable есть 3 книги. (2 предыдущих плюс "призрак" с фиктивными значениями.) Фиктивные значения получены из метода saveChanges(), который сохраняет текущие поля.
Вот изображение программы с лентой (север), полями (центр) и таблицей JT (внизу).
Вы можете увидеть дополнительный ряд, неожиданный.
Теперь давайте посмотрим код:
Когда я нажимаю на строку JTable, я запускаю этот метод:
table.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
if (table.getSelectedRow() > -1) {
Book book = ((TableATM) table.getModel()).getBook(table
.convertRowIndexToModel(table.getSelectedRow()));
getStatesManager().getState().selectBook(book);
}
}
});
Это вызывает selectBook из класса UnboundState. Для этого окна есть два состояния: BoundState и UnboundState. UnboundState используется, когда поля пусты. Когда поля содержат данные книги (например, после удаленного поиска в Интернете с помощью ISBN), они немедленно сохраняются, и состояние становится связанным.
После поиска, о котором я говорил выше, состояние остается тем же, что и первоначальное, я имею в виду UnboundState: поиск изменяет только JTable, а не поля.
Итак, SelectBook UnboundState срабатывает:
@Override
public void selectBook(Book book) {
statesManager.setBound(book);
}
Цель метода setBound - изменить состояние:
public void setBound(Book book) {
state = new BoundState(book, this, bookWindow,
new ChoiceISBNDialog(bookWindow));
}
вот конструктор, вызываемый setBound:
public BoundState(Book book, StatesManager statesManager,
BookWindow bookWindow, ChoiceISBNDialog choice) {
this.statesManager = statesManager;
this.bookWindow = bookWindow;
this.choice = choice;
SwingUtilities.invokeLater(() -> {
statesManager.enableFields(true);
if (statesManager.getState().getName().equals("BOUND"))
saveChanges();
statesManager.displayBook(book);
statesManager.setCaretsToZero();
bookWindow.ribbon.btn_revertChanges.setEnabled(false);
bookWindow.ribbon.btn_storeInTable.setEnabled(false);
});
}
Важно, что метод saveChanges () не должен вызываться, потому что текущее состояние при вызове invokeLater - "UNBOUND".
Но когда я отлаживаю программу, я получаю следующее: методы запускаются в соответствии с заданным мною запахом, за исключением того, что отладчик не входит в invokeLater, он продолжается, и методы заканчиваются, последним является JTable слушатель. но я поставил точку останова в методе saveChanges () и вижу, что метод saveChanges () запускается ПОСЛЕ конца слушателя JTable. Это эффект invokeLater, который я предполагаю. Но в то время состояние стало "BOUND", и метод saveChanges считает, что книга на самом деле является новой, и пытается ее сохранить.
Как я мог заставить это работать? Я попытался вызвать invokeAndWait, но программа зависает (он определенно останавливается даже через 1 минуту или более).
благодарю вас
Оливье