The best approach is to use:
Creating the frame does not affect the swing thread, because it does not compute the component till it is asked to make it visible.
The problem is when the threads needs to render a componenet, and the code is not running in the swing thread. (This has been enforced in JavaFX)
JFrame f = new JFrame();
//Java 7
SwingUtilities.invokeLater(new Runnable() {
public void run() {
f.setVisible(true);
}
});
//Java 8
SwingUtilities.invokeLater(() -> f.setVisible(true));
The other thing is that you are mixing frameworks, this is never a good idear. Don't use the awt thread to render swing componentes. Even if Swing does call the awt thread, you should not mix bought your self. Imagin that Swing invokeLater implementation changes , you would be using the old implementation calling awt directly.
EDIT:
To clarify the difference:
java.awt.EventQueue.invokeLater(() -> {
JFrame f = new Main();
f.setVisible(true);
});
The first code is asking Swing (or awt really) to queue this request and handle it when it can.
JFrame f = new Myframe();
f.setVisible(true);
The second code runs in the current Thread from where it has been called. Could be the swing thread or any other.