При создании окна создаётся
Event Dispatch Thread, внутри которого крутится бесконечный цикл, на каждой итерации достающий событие из очереди и запускающий обработчик для него. Бесполезно использовать циклы для изменения интерфейса, так как все изменения просто встанут в очередь и будут выполнены только на одной из следующих итераций цикла событий. А так как ваш бесконечный
while
работает на порядки быстрее, чем цикл
Потока Обработки Событий, очередь событий просто забивается.
System.out.println()
- операция блокирующая, поэтому её вызов даёт время циклу событий разобрать очередь.