You must dispose the frame, invoking the dispose method in your window listener or using setDefaultCloseOperation. For the argument of the last one, you can use two options: DISPOSE_ON_CLOSE or EXIT_ON_CLOSE.
DISPOSE_ON_CLOSE only dispose the frame resources.
EXIT_ON_CLOSE disposes the frame resources and then invokes System.exit.
There is no real difference between the two unless you have non daemon threads. I prefer to use DISPOSE_ON_CLOSE because this way I'm able to notice if I forgot to terminate a thread, because the JVM will stop if there are no more threads running. That's also the reason closing a Frame without disposing will not terminate the application, since Swing creates a thread to handle events that is terminated only when dispose is invoked.