Full Screen Help Wanted

I’ve tried to find some information on building a full screen game but what I’ve found isn’t as comprehensive as I wanted. What should I draw on? A Frame, JFrame, Canvas, JCanvas or a Window? I don’t plan to use any other GUI controlls (all is rendered by the game itself). I want a clean and easy way to draw onto the screen basically.

Window & Canvas are the 2 classes that reveal the calls necessary to create a BufferStrategy.

You should realy use a Canvas, so you can add it to whatever Container you are using (e.g. an Applet, Frame, JFrame etc etc)

Some (old!) code of mine for making a fullscreen display. (cation: probably not very robust :S )

      private void createFullscreenWindow()
      {
            fullscreenWindow = new Window(mainFrame);
            
            graphicsDev.setFullScreenWindow(fullscreenWindow);
            
            // Check if possible to switch display modes
            if (graphicsDev.isDisplayChangeSupported() )
            {
                  // Changes supported, all good :)
            }
            else
            {
                  // Cannot change, must run in window.
                  JOptionPane.showMessageDialog(null,
                                                                  "Display mode cannot be changed, running in a window.",
                                                                  "Cannot change display mode",
                                                                  JOptionPane.ERROR_MESSAGE);
                  
                  fullscreenWindow = null;
                  graphicsDev.setFullScreenWindow(null);
                  useFullscreen = false;
                  return;
            }
            
            currentDisplayMode = new DisplayMode(xResolution, yResolution, colourDepth, DisplayMode.REFRESH_RATE_UNKNOWN);
            graphicsDev.setDisplayMode(currentDisplayMode);
            
            fullscreenWindow.createBufferStrategy(2);
            bufferStrategy = fullscreenWindow.getBufferStrategy();
            
            graphicsConfig = fullscreenWindow.getGraphicsConfiguration();
            
            
            mainFrame.setIgnoreRepaint(true);
            fullscreenWindow.setIgnoreRepaint(true);
      }

Worked for me :slight_smile: Of course you need to restore the old display mode on exit and a couple of other housekeeping things as well.

Take a look at this site:

http://java.sun.com/docs/books/tutorial/extra/fullscreen/

What do you guys think of this GameCanvas i wrote:

/*
 * Created on 2004-mar-15
 */
package tests;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;

/**
 * The GameCanvas class provides the basis for a game user interface.
 * 
 * @author Johan Tibell
 * @version 1.0
 */
public class GameCanvas extends Canvas
{
      /** Decides if we are drawing on the back buffer or not. */
      private boolean drawOnBuffer = true;
      /** The buffer strategy currently used. */
      private BufferStrategy strategy;
      
      /**
       * Creates a new instance of a GameCanvas.
       */ 
      GameCanvas()
      {
            super();
      }
      
      /**
       * Flushes the off-screen buffer to the display.
       */
      public void flushGraphics()
      {
            // If the back buffers haven't yet been initialized do nothing.
            if (strategy != null)
            {
                  // If the buffer is intact draw it on the screen.
                  if (!strategy.contentsLost())
                  {
                        // The buffer strategy needs to draw its buffer on the
                        // screen not on its own buffer.
                        drawOnBuffer = false;
                        strategy.show();
                        // Any other drawing should be done on the buffer.
                        drawOnBuffer = true;
                  }
            }
      }
      
      /**
       * Obtains the Graphics object for rendering a GameCanvas.
       * 
       * @return the Graphics object that renders to this GameCanvas' off-screen buffer 
       */
      public Graphics getGraphics()
      {
            if (drawOnBuffer)
            {
                  if (strategy == null)
                  {
                        createBufferStrategy(2);
                        strategy = getBufferStrategy();
                  }
                  
                  return strategy.getDrawGraphics();
            }
            // When drawing the buffer onto the screen we need to use the
            // real Graphics object.
            else
                  return super.getGraphics();
      }
            
      /**
       * Paints this GameCanvas.
       * 
       * @param g the Graphics object with which to render the screen
       */
      public void paint(Graphics g)
      {
            // There's no need to call the super class paint method since
            // it only clears the canvas to its background color. Instead
            // we try to paint the last frame again if it hasn't been
            // destroyed.
            flushGraphics();
      }
}

The drawOnBuffer is used since I wanted to use the getGraphics() as my method name (and the dubble buffering thing uses it for other purposes).

Could I just add this to a Frame and then set full screen? Or should I set full screen first and add it later?

Could someone please help me write a minimal code that attaches this canvas to a frame in fullscreen mode. Note that a call to setSize() of the canvas must be done before using it!

This is my test program for the windowed version and it works fine:


/*
 * Created on Apr 27, 2003
 */
package tests;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;

/**
 * @author Johan Tibell
 */
public class GameCanvasTest
{
      public static void main(String[] args)
      {
            testGraphics();
      }
      
      public static void testGraphics()
      {
            JFrame mainFrame = new JFrame("GameCanvas Test");
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
            GameCanvas game = new GameCanvas();
            game.setSize(640, 480);
            
            mainFrame.getContentPane().add(game);

            mainFrame.pack();
            mainFrame.setVisible(true);
            
            while (true)
            {
                  Graphics g = game.getGraphics();
                  g.setColor(Color.WHITE);
                  g.fillRect(0, 0, 640, 480);
                  game.flushGraphics();
                  g.dispose();
                  try { Thread.sleep(20);      } catch (InterruptedException e) {}
            }            
      }
}

One piece of advice: do not use Window as a full screen window, use Frame instead.

I won’t go into details, but it really screws DDraw/D3D if you go fullscreen with a window and not a frame. We fixed some of the problems caused by this in 1.5 (and updated the javadoc for setFullScreenWindow to advise not to use window), but you never know.

http://java.sun.com/j2se/1.5.0/docs/api/java/awt/GraphicsDevice.html#setFullScreenWindow(java.awt.Window)

[quote]One piece of advice: do not use Window as a full screen window, use Frame instead.

I won’t go into details, but it really screws DDraw/D3D if you go fullscreen with a window and not a frame. We fixed some of the problems caused by this in 1.5 (and updated the javadoc for setFullScreenWindow to advise not to use window), but you never know.

http://java.sun.com/j2se/1.5.0/docs/api/java/awt/GraphicsDevice.html#setFullScreenWindow(java.awt.Window)
[/quote]
So my best bet would be to make a Frame my fullscreen “window” and add a Canvas on it to draw on. Should I add the canvas before or after I go into fullscreen mode?

[quote]One piece of advice: do not use Window as a full screen window, use Frame instead.
[/quote]
Thats… odd. I never had a problem doing this ages ago (just after the first proper 1.4.0 release). Is this something thats got worse or is it only really a problem on crappy chips or obscure configurations?

It has always been the case, you just got lucky.

Usually the problems show up when you try to alt+tab back and forth from/to the full screen app (which is using bufferstrategy) or change the display modes, in other words, stress tests.