Чтобы добавить к ответу объекта выше:
Если вы используете приложение на основе пользовательского интерфейса, вы должны использовать потоки SwingWorker для выполнения любой работы, не связанной с графическим интерфейсом. Все задачи Swing, например, выполняются в потоке диспетчеризации событий (EDT). Если вы хотите запустить код в EDT, вам следует использовать методы SwingUtilities. invokeLater () добавляет задачу в текущую очередь задач в EDT, а invokeAndWait () запускает задачу и блокирует до ее завершения.
Если вы хотите убедиться, что что-то не работает в EDT, вы можете использовать вызов SwingUtilities.isEventDispatchThread (), чтобы определить, является ли текущий поток EDT.
Если вы инициализируете свой GUI из метода main () вашего приложения, убедитесь, что любые вызовы, чтобы сделать компоненты GUI видимыми, или вообще любое взаимодействие с GUI выполняется на EDT.