Monday, August 20, 2007

Toggle Fullscreen Mode

Purpose

To show how you can switch a window between being windowed and fullscreen with the press of a button.


Diving Right In

Ok, so in a previous post I showed how you can start a JFrame in fullscreen mode by removing decorations on the frame and also by changing the screens display mode. Well now I am going to use that code modify it so that you can toggle or switch between windowed and fullscreen modes just by pressing a single key.


Windowed Mode

The following code will change a fullscreened JFrame back to windowed mode.

//set the display mode back to the what it was when
//the program was launched.
device.setDisplayMode(dispModeOld);

//hide the frame so we can change it.
setVisible(false);

//remove the frame from being displayable.
dispose();

//put the borders back on the frame.
setUndecorated(false);

//needed to unset this window as the fullscreen window.
device.setFullScreenWindow(null);

//make sure the size of the window is correct.
setSize(800,600);

//recenter window
setLocationRelativeTo(null);

//reset the display mode to what it was before
//we changed it.
setVisible(true);
There are a couple of key function calls here, one is the dispose call since it allows us to add the decorations back onto the window. Without it right before the call to setUndecorated we would get a java.awt.IllegalComponentStateException with the message "The frame is displayable". We could however remove the call to setUndecorated but then there would be no Border (i.e no title bar, minimize, maximize, or exit buttons) around the window when in windowed mode.
Another nice call that you could remove without any problems is the setLocationRelativeTo(null); this call centers the window on screen. You need to make sure you call this only after the size has been reset since it won't be centered if you do that.

One of the most important calls is the first one displayModeOld is a member variable that we must set in the JFrame's constructor and anytime before we switch to a custom screen mode. Idea: What would be a good idea is to check to see if the current screen mode is what we want and if not then save the old one and change to one we want.

Fullscreen Mode

Ok, so now that we can switch back to windowed here again is the code for changing to fullscreen mode there are a couple of things that needed to be added since we need to be doing this while the window is already being displayed.
//save off the old display mode.
dispModeOld = device.getDisplayMode();

//hide everything
setVisible(false);

//remove the frame from being displayable.
dispose();

//remove borders around the frame
setUndecorated(true);

//make the window fullscreen.
device.setFullScreenWindow(this);

//attempt to change the screen resolution.
device.setDisplayMode(dispMode);

//show the frame
setVisible(true);

Notice that we first save the current screen mode so the next time the window is changed we can reset the screen mode back to what it was before we changed it.


Encapsulation

Alright, now we need to put it all in one nice easily managable function.

/**
 * Method allows changing whether this
 * window is displayed in fullscreen or
 * windowed mode.
 *
 * @param fullscreen true = change to fullscreen,
 *                   false = change to windowed
 */
public void setFullscreen(boolean fullscreen) {
   //are we actually changing modes.
   if( this.fullscreen != fullscreen ) {

      //change modes.
      this.fullscreen = fullscreen;

      // toggle fullscreen mode
      if(!fullscreen) { 

         //change to windowed mode.

         //...windowed mode code.

      }else{
         //change to fullscreen.

         //...fullscreen mode code.

      } // end if

      //make sure that the screen is refreshed.
      repaint();
   }
}


We only want to actually change display modes if we are switching from fullscreen to windowed or vice versa, since trying to set some of the properties will cause exceptions to be thrown.


Seeing Is Believing