I gave luke’s example a shot and still ran into some problems (in some cases worse problems) 
I’m just going to post my code and maybe someone can tell me what I’m doing wrong… I’ve since reverted back to my original code, which at least seems to display stuff without the major flickering issues that I was having with Luke’s example. No doubt it was user error on my end…
A lot of this was adapted from a site online, so chances are it’ll look familiar to anyone who’s been to the same site, which I don’t have handy at the moment, unfortunately.
public class BBClient extends JFrame implements Runnable, ActionListener, Observer {
private static final int NUM_BUFFERS = 2;
private static final int NO_DELAYS_PER_YIELD = 16;
private static int MAX_FRAME_SKIPS = 5;
private int period;
private GraphicsDevice gd;
private Graphics2D gScr;
private BufferStrategy bufferStrategy;
private HashMap images;
private Thread animator;
private boolean running;
// Button Rectangles/Areas
private Rectangle leftRect;
private Rectangle topRect;
private Rectangle rightRect;
private Rectangle bottomRect;
private Rectangle nukeRect;
private Rectangle cannonRect;
private Rectangle connectRect;
private Rectangle chatButtonRect;
private Rectangle chatBarRect;
private Rectangle switchRect;
private Rectangle contentRect;
// Hover vars -- Right now I only have the "connect" button implemented...
private boolean isOverConnectRect;
// Stage vars
private int stage;
private JPanel gridPane;
// at different “stages,” the user can interact with different things. Not important right now
private JLabel bgImage;
private JTextField loginField;
private static final long serialVersionUID = 1L;
public BBClient(int period) {
super("MyGame");
this.period = period;
setIgnoreRepaint(true);
stage = 0; // no importance right now
loadImages();
createRects();
initFullScreen();
// I colored the background green to see what space the JPanel actually occupies.
// From the looks of it, the JPanel is in the right space in the GUI, and it's the right size.
// However the components within it are all screwed up and out of place.
gridPane = new JPanel();
gridPane.setBackground(Color.green);
// Load the "login" image that will serve as a sort of splash/intro screen while the player logs in
try {
String url = System.getProperty("user.dir")+ "\\view\\images\\login.png";
bgImage = new JLabel(new ImageIcon(new URL("file:" + url)));
} catch (Exception e) {
System.out.println("wra!");
}
// I've tried all sorts of ways to reposition the bgImage JLabel, to no avail.
// It always appears offset to the right in the JPanel no matter what I do.
// I've also tried to add a JTextField here, also to no avail. textfield.setSize(x, y) also seems to have no effect.
gridPane.add(bgImage);
gridPane.add(new JTextField());
add(gridPane);
gameStart();
}
// ImageLoader is a separate class
public void loadImages() {
// … this part’s not a problem, but it sure is too lengthy to post here :)
}
// We'll be able to interact with some of these later on, but for now we're just using them for image placement.
public void createRects() {
leftRect = new Rectangle(0, 0, 173, 600);
// … etc
}
public void initFullScreen() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
gd = ge.getDefaultScreenDevice();
setUndecorated(true);
setIgnoreRepaint(true);
setResizable(false);
if (!gd.isFullScreenSupported()) {
System.out.println("Couldn't get into full-screen...");
System.exit(0);
}
gd.setFullScreenWindow(this); // switch on full-screen mode
setDisplayMode(800, 600, 32); // set the resolution so the GUI fits
setBufferStrategy(); // set up the drawing/rendering mechanisms
}
private void setDisplayMode(int width, int height, int bitDepth) {
if (!gd.isDisplayChangeSupported()) {
System.out.println("Display mode changing not supported");
return;
}
DisplayMode dm = new DisplayMode(width, height, bitDepth,
DisplayMode.REFRESH_RATE_UNKNOWN);
try {
gd.setDisplayMode(dm);
} catch (IllegalArgumentException e) {
System.out.println("Error setting Display mode (" + width + "," + height + "," + bitDepth + ")");
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
}
private void setBufferStrategy() {
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
createBufferStrategy(NUM_BUFFERS);
}
});
} catch (Exception e) {
System.out.println("Couldn't start page flipping...");
System.exit(0);
}
// Allow the new BufferStrategy enough time to execute
try {
Thread.sleep(500); // 0.5 sec
} catch (InterruptedException ex) {
}
bufferStrategy = getBufferStrategy(); // store for later
}
// Start our main game thread
private void gameStart() {
if (animator == null || !running) {
animator = new Thread(this);
animator.start();
}
}
public void run() {
// Framerate and timer settings have no relevance to my current problem
running = true;
while (running) {
screenUpdate();
// framerate stuff goes below here…
}
closeGame();
}
public void screenUpdate() {
try {
gScr = (Graphics2D) bufferStrategy.getDrawGraphics();
gameRender();
gScr.dispose();
if (!bufferStrategy.contentsLost()) {
bufferStrategy.show();
} else {
System.out.println("Contents Lost");
}
Toolkit.getDefaultToolkit().sync();
} catch (Exception e) {
e.printStackTrace();
running = false;
}
}
// Here's where the actual drawing takes place. This is called from screenUpdate which is called from
// our main run loop. The first part of this section simply draws my HUD. It basically creates a "BorderLayout"
// of my own, with images on the left, top, right and bottom. The middle of the screen is left empty and shouldn't
// be drawn in.... yet.
public void gameRender() {
BufferedImage image;
TexturePaint imagePaint;
image = (BufferedImage) images.get("left.png");
imagePaint = new TexturePaint(image, leftRect);
gScr.setPaint(imagePaint);
gScr.fill(leftRect);
image = (BufferedImage) images.get("top.png");
imagePaint = new TexturePaint(image, topRect);
gScr.setPaint(imagePaint);
gScr.fill(topRect);
image = (BufferedImage) images.get("right.png");
imagePaint = new TexturePaint(image, rightRect);
gScr.setPaint(imagePaint);
gScr.fill(rightRect);
image = (BufferedImage) images.get("bottom.png");
imagePaint = new TexturePaint(image, bottomRect);
gScr.setPaint(imagePaint);
gScr.fill(bottomRect);
// If this is the Login stage (which, right now, is the only stage that exists), draw the splash logo
// and login components (JTextField and JButton, for example)
if (stage == 0) {
Graphics2D g2d = (Graphics2D)gScr.create(173, 93, 550, 421);
gridPane.paint(g2d);
// gridPane.paintComponents(g2d) results in 2 of my "splash images" being drawn on the screen.
// One is solid and displayed off-center, while the other is flickering with a green background
// (I set the gridPane JPanel's background to green, if you recall).
// gridPane.repaint() causes the entire screen to flicker. The HUD images and the JPanel flicker between one another.
// Right now gridPane.paint(g2d) yields the best results, showing the solid splash image from my JLabel (no flickering),
// but showing it off-centered. Again, my JTextField wouldn't show up either when I tried to add it.
// Trying to reposition the JComponents yields no results. The only way I seem to be able to move anything is if
// I move the rectangle that it's all drawn in. This is unacceptable, as it would cause it to cover up the other
// elements on the screen, such as the HUD.
}
// Not important for the purposes of my current problem. It works when I actually have it implemented.
if (isOverConnectRect) {
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
image = (BufferedImage) images.get("h_connect.png");
imagePaint = new TexturePaint(image, connectRect);
gScr.setPaint(imagePaint);
gScr.fill(connectRect);
} else {
this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
public void closeGame() {
Window w = gd.getFullScreenWindow();
if (w != null) {
w.dispose();
}
gd.setFullScreenWindow(null);
System.exit(0);
}
public void update(Observable o, Object arg) {
}
public void actionPerformed(ActionEvent e) {
}
public static void main(String[] args) {
int p = 1;
new BBClient(p).setVisible(true);
// I've noticed that removing the call to setVisible here causes my JPanel to not get drawn at all...
// I thought JFrames were visible by default?
}
}
I appreciate the help of anyone who’s willing to take the time to sift through my crappy coding and help me figure out what I’m doing wrong. This seems to be a question that’s asked all-too-often, yet it’s strange how it’s still so difficult to find a straight answer. Thanks again.