Most people choose Swing since it is more powerful, usually looks nicer (themes etc) and more standard. The main problem with mixing light and heavy weight components is render order, e.g. for popups like menu items. Sometimes JPopupMenu.setDefaultLightWeightPopupEnabled solves the problem.
Singletons are generally not a good design pattern. There are many ways of decoupling your game loop, one easy choice:
public class AbstractGame {
public void run() {
create();
... start game loop ...
render();
dispose();
}
public abstract void create(); //allocate resources
public abstract void render(); //render resources
public abstract void dispose(); //destroy resources
}
Another common solution is to use a “listener” interface. So, instead of calling methods in AbstractGame, you pass a listener to the Game class at creation time, and then the Game class calls the listener’s methods during the game loop. This makes it easy to support multiple backends and distributions.
Ultimately though, if you plan to make a relatively complex game (i.e. one that requires a scene graph, in-game UI, tiled maps, sprite sheet animations, physics, etc) you should not use Java2D. Not only is it slow, bulky to use, and doesn’t give you anything “out of the box,” but it only distributes to desktop and applets (which are now defunct, for all intents and purposes).
Instead it would make sense to use a game-specific framework built on OpenGL rendering, like LibGDX. 