Obviously, a function that is constantly executed in the actionPerformed method will effectively disable the rest of my GUI.
This is a good observation and shows that you understand the basic rule when working with Swing.
Your game is most likely event driven (correct me if I am wrong), so the action performed by the button should simply set the program to a new state, waiting for further events. This should not take much time, and usually this is done directly by the EDT.
Of course, if you want to make a fancy animation of the beginning of a new game, which should be performed in a separate thread, in this case you just start the animation stream (I would recommend using SwingWorker, though) from inside the actionPerformed method, and then return.
In the code, I think it would look something like this:
go.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
source share