Все, что обращается к объектам Swing, должно делать это через поток диспетчеризации событий (EDT).Есть одно маленькое исключение из этого (которое я упомяну позже).Целью EDT является обработка любых событий, которые могут произойти из-за ввода-вывода (события мыши и клавиатуры).Довольно часто это может означать изменение макета вашего графического интерфейса.Swing не был разработан, чтобы быть потокобезопасным, а это означает, что если два потока пытаются изменить один и тот же компонент одновременно, вы можете получить поврежденный графический интерфейс.Поскольку уже существует один известный поток для доступа к компонентам Swing (EDT), никакой другой поток не должен пытаться изменять их или даже читать их состояние.
Теперь, в исключительном случае, когда вы можете манипулировать объектами Swing снаружииз EDT.Прежде чем какие-либо компоненты станут видимыми, IO не сможет инициировать события.Поэтому основной поток может настроить графический интерфейс Swing, а затем установить один JFrame, который будет видимым.Поскольку теперь в видимой рамке могут происходить события ввода-вывода, и основной поток не должен пытаться изменять какие-либо компоненты Swing.Эту опцию следует использовать только для запуска графического интерфейса, и на самом деле только с игрушечными проблемами.
Я хочу сказать, что следующее хорошо и не вызовет проблем, если вы просто поиграете свещи.
public static void main(String[] args) {
// create components
JFrame f = new JFrame();
...
// do layout and other bits of setup
// show gui to user
f.setVisible(true);
}