EDT против слушателя

Хорошо, я знаю, что только что задал аналогичный вопрос, но я попытался упростить его, поэтому я использовал то, что казалось плохим примером, с проблемой, которую я не ожидал, таким образом получив ответы, которые не решили мою проблему. вопрос.

У меня такая установка:

У меня есть метод в EDT. Он циклически перебирает кучу JTextAreas и удаляет пустые.

Так в чем подвох?

Каждый раз, когда JTextArea удаляется, запускается прослушиватель, который затем визуально обновляет графический интерфейс (вытягивает все визуальные объекты ниже JTextArea вверх).

Так что же происходит? Что ж, по мере выполнения цикла JTextAreas не удаляются визуально, они добавляются в очередь EDT (я предполагаю), а затем все они удаляются сразу после завершения цикла. Что происходит тогда, так это то, что все слушатели срабатывают одновременно и портят весь графический интерфейс.

Поскольку все запускается в EDT, я ожидал, что код будет действовать следующим образом:

  • Начать цикл
  • Найти пустой JTextArea
  • Completly remove an empty JTextArea -> triggers the listener
    • Execute the code in the listener
  • Продолжить цикл
  • Найдите следующий пустой JTextArea
  • Промойте и повторяйте, пока не будет достигнут конец цикла.

Как я могу заставить свою программу вести себя так?

Должен ли я создать новый поток, который ищет пустые JTextAreas, и выполнять удаление в invokeLater(new Runnable())? Фактический код, который выполняет поиск, на самом деле не предназначен для процессора, он проходит только через arrayList JTextAreas, а проверка getText().equals(""), поэтому я действительно не думаю, что это необходимо...


person Karlovsky120    schedule 01.03.2013    source источник
comment
Чтобы быстрее получить помощь, опубликуйте SSCCE.   -  person Andrew Thompson    schedule 01.03.2013
comment
Это концептуальный вопрос. SSCCE не требуется.   -  person Karlovsky120    schedule 01.03.2013
comment
Я не вижу, чтобы удаление кучи компонентов было причиной того, что ваш пользовательский интерфейс испортился (я могу в это поверить, но я думаю, что происходит что-то еще). Если вас действительно беспокоит последовательность событий, вы можете вместо этого использовать SwingUtilities.invokeAndWait, который будет ждать, пока метод run runnable не завершится, в отличие от invokeLater, который поместит runnable в конец очереди событий и вернет (почти) немедленно ...   -  person MadProgrammer    schedule 01.03.2013
comment
@ Karlovsky120 Тогда ждите только концептуальных ответов. Предлагаемые нами решения могут не соответствовать вашим конкретным потребностям.   -  person MadProgrammer    schedule 01.03.2013
comment
Единственное, что меня интересует, это убедиться, что элемент удален всеми возможными способами в тот момент, когда программа достигает строки кода .remove(). Как бы то ни было, визуальное удаление, кажется, происходит только после того, как метод исчерпал себя. Поскольку все удаления происходят одновременно, все слушатели срабатывают одновременно, получая доступ к другим элементам и перемещая их одновременно.   -  person Karlovsky120    schedule 01.03.2013
comment
Содержит ли ваш цикл revalidate/repaint вызовы родительского контейнера, из которого удаляются компоненты? Это может быть одной из проблем, но без кода сложно получить верный ответ.   -  person nIcE cOw    schedule 01.03.2013
comment
As it is, the visual removal seems to happen only after the method has ran it's course. Это верно. Код в EDT выполняется последовательно. Поэтому, когда вы нажимаете кнопку, чтобы начать обработку, которая, в свою очередь, выполняет цикл, тогда графический интерфейс не перерисовывается до тех пор, пока не завершится выполнение исходного цикла. Если вы хотите удалить по одному компоненту за раз, это подразумевает какую-то анимацию, а это значит, что вы должны использовать таймер. Таким образом, каждый раз, когда срабатывает таймер, вы находите компонент и удаляете его. Когда больше нет компонентов для удаления, вы останавливаете таймер.   -  person camickr    schedule 01.03.2013


Ответы (1)


Удалить одну текстовую область. определить, есть ли что еще удалить, если да, поставьте задачу в очередь, используя SwingUtilities.invokeLater(), которая вызывает обратный вызов в текущем коде. повторяйте, пока не будут удалены все текстовые области.

person jtahlborn    schedule 01.03.2013