If you're starting with Swing, you may not know about the Event Dispatch Thread yet. This is a thread where all Swing events are being processed.
The first version of your program calls Thread.sleep on the current thread, which does not affect the Event Dispatch Thread. The second version of your program uses an ActionListener, which will be executed in the Event Dispatch Thread. This means that this time, Thread.sleep is invoked in the Event Dispatch Thread, which is going to block all other painting events, causing the freeze that you are experiencing.
In moveBall, try to add something like System.out.println(Thread.currentThread().getName()) to see the difference.