FSEM

Till now my games have been either windowed or FSEM. How can i switch back and fourth. My code fails… miserably.

public void setFullScreen(DisplayMode displayMode) {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setUndecorated(true);
        frame.setIgnoreRepaint(true);
        frame.setResizable(false);

        device.setFullScreenWindow(frame);

        if (displayMode != null && device.isDisplayChangeSupported()) {
            try {
                device.setDisplayMode(displayMode);
            } catch (IllegalArgumentException ex) { }
            // fix for mac os x
            frame.setSize(displayMode.getWidth(),
                displayMode.getHeight());
        }
        // Avoid potential deadlock in 1.4.1_02
        try {
            EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    frame.createBufferStrategy(NUM_BUFFERS);
                }
            });
        }
        catch (InterruptedException ex) {
            // ignore
        }
        catch (InvocationTargetException  ex) {
            // ignore
        }
    }
   public void restoreScreen() {
        //Window window = device.getFullScreenWindow();
        //if (window != null) {
            //window.dispose();
        //}
		
		final JFrame frame = (JFrame)device.getFullScreenWindow();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setUndecorated(true);
        frame.setIgnoreRepaint(true);
        frame.setResizable(false);

		DisplayMode displayMode = getCurrentDisplayMode();
        if (displayMode != null && device.isDisplayChangeSupported()) {
            try {
                device.setDisplayMode(displayMode);
            } catch (IllegalArgumentException ex) { }
            // fix for mac os x
            frame.setSize(displayMode.getWidth(),
                displayMode.getHeight());
        }
        // Avoid potential deadlock in 1.4.1_02
        try {
            EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    frame.createBufferStrategy(NUM_BUFFERS);
                }
            });
        }
        catch (InterruptedException ex) {
            // ignore
        }
        catch (InvocationTargetException  ex) {
            // ignore
        }
		
		
        device.setFullScreenWindow(null);

There are a pair of methods in my screenmanager class. Here is what is in my manager:

public void windowedMode()	{
		fullscreen = false;
		screen.restoreScreen();
	}
	
	//Set to FSEM
	public void fullscreenMode()	{
		fullscreen = true;
		DisplayMode displayMode =
            screen.findFirstCompatibleMode(POSSIBLE_MODES);
        screen.setFullScreen(displayMode);
		
	}

screen is an instance of the screenManager. I feel stupid :\

I use the below code inside a class that extends JFrame to switch between Full screen & window mode in the middle of the game (after pausing the game loop rendering thread) :

It works mostly in Java 1.5, but sometimes it caused a VM crash with a hs_pid output file etc. On Mustang it fails almost always, it only works sometimes. I’m not sure why.

public void setFullScreen(boolean fullScreen) throws IllegalArgumentException{
if (isFullScreen() == fullScreen){
// we’re already in fullscreen, so return.
return;
}
if (fullScreen){
setResizable(false);
device.setFullScreenWindow(this);
if (displayMode != null && device.isDisplayChangeSupported()){
try{
device.setDisplayMode(displayMode);
System.out.println(“display mode set”);
}
catch(IllegalArgumentException e){
System.out.println(“display mode not supported”);
device.setFullScreenWindow(null);
throw e;
}
}else{
device.setFullScreenWindow(null);
throw new IllegalArgumentException(“device.isDisplayChangeSupported() == false”);
}
}
else{
device.setFullScreenWindow(null);
setResizable(true);
}
createBufferStrategy(Main.getPlayingController().getView().getNumBuffers());
}

public boolean isFullScreen(){
		if (device.getFullScreenWindow() == null){
			return false;
		}
		return true;
}

Hrm, havn’t tried it yet but it seems like we are doing the same thing, or I was doing that then I elaborated.

What happens when I move back to windowed mode? Is it simply resetting the display mode? When I do that i get an empty window.

I am guessing you do key detection in your subclass of JPanel? I do mine in the Subclass of canvas so its more convenient to have the code in the canvas.

You seem to just be setting the fullscreen window to nothing, then creating a new buffer strategy. That doesn’t appear to work over here, I get a window that doesn’t have focus and is not being drawn in.

I’ve got a window listener on the JFrame. Maybe that’s what’s grabbing the focus back:

public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowClosing(WindowEvent e){
close();
}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {
if (Main.getPlayingController().getView() != null){
Main.getPlayingController().getView().requestFocus();
}
}

That Isn’t it.

Here is my subclass of JFrame

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class RunnerApp extends JFrame	{
	public static final int WIDTH = 640, HEIGHT = 480;
	public static GameManager manager;
	
	public static void main(String[] args)	{
		RunnerApp frame = new RunnerApp();
		manager = new GameManager();
		manager.setPreferredSize(new Dimension(WIDTH, HEIGHT));
		
		frame.add(manager);
		frame.pack();
		frame.setResizable(false);
		
		manager.init();
		frame.setVisible(true);
		manager.start();
	}
	
	public RunnerApp()	{
		super("Game");
		addWindowListener(new WinHandler());
	}
	
	private class WinHandler extends WindowAdapter	{
		public void windowClosing(WindowEvent e)	{
			manager.stopGame();
		}
		
		public void windowActivated(WindowEvent e)	{
			manager.setPaused(false);
		}
		
		public void windowDeactivated(WindowEvent e)	{
			manager.setPaused(true);
		}
		
		public void windowOpened(WindowEvent e)	{
			requestFocus();
		}
	}
}

And my “manager” class

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.sound.sampled.AudioFormat;
import javax.sound.midi.*;

import java.io.*;
import javax.sound.sampled.*;
import java.text.DecimalFormat;
import java.net.URL;


public class GameManager extends GameCanvas {
	private static final int REFRESH_RATE =
        DisplayMode.REFRESH_RATE_UNKNOWN;
    protected static final DisplayMode POSSIBLE_MODES[] = {
        new DisplayMode(800, 600, 32, REFRESH_RATE),
        new DisplayMode(800, 600, 24, REFRESH_RATE),
        new DisplayMode(800, 600, 16, REFRESH_RATE),
        new DisplayMode(640, 480, 32, REFRESH_RATE),
        new DisplayMode(640, 480, 24, REFRESH_RATE),
        new DisplayMode(640, 480, 16, REFRESH_RATE),
    };
	private ScreenManager screen;
	private boolean fullscreen;

    private int fps;          // frames per second
	private ResourceManager resourceManager;
	private KeyState keys; //keys
	
	public GameManager()	{
		addKeyListener(new KeyHandler());
	}
	
	// Driver to start the game
    public static void main(String[] args) {
        RunnerFullScreen canvas = new RunnerFullScreen();
        canvas.start();
    }
	
	// Set full-screen mode and start game
    public void start() {
        screen = new ScreenManager();
        DisplayMode displayMode =
            screen.findFirstCompatibleMode(POSSIBLE_MODES);
        screen.setFullScreen(displayMode);
		fullscreen = true;

        // Add canvas after entering FSEM and changing mode
        JFrame frame = screen.getFullScreenWindow();
        frame.add(this);  // add components
        frame.validate(); // layout components

        init();
        startGame();
    }
	
    public void init() {
        // Load images and create sprites
		resourceManager = new ResourceManager(GraphicsEnvironment
            .getLocalGraphicsEnvironment()
            .getDefaultScreenDevice()
            .getDefaultConfiguration());
    }

    public void Update(long elapsedTime) {
        if (elapsedTime > 0) { // update frame rate
            fps = (int) (1000L / elapsedTime);
        }
    }

	//Restore to windowed screen
	public void windowedMode()	{
		fullscreen = false;
		screen.restoreScreen();
		createBufferStrategy(NUM_BUFFERS);
	}
	
	//Set to FSEM
	public void fullscreenMode()	{
		fullscreen = true;
		DisplayMode displayMode =
            screen.findFirstCompatibleMode(POSSIBLE_MODES);
        screen.setFullScreen(displayMode);
		
	}

	// Override superclass to restore the screen
    public void exitGame() {
        screen.restoreScreen();
		fullscreen = false;
        super.exitGame();
    }
	
    public void draw(Graphics g) {
        if (g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(
                RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }

        // Render game here
        g.setColor(Color.GREEN);
        g.fillRect(0, 0, getWidth(), getHeight());

        // Display data
        g.setColor(Color.WHITE);
        g.setFont(new Font("Dialog", Font.PLAIN, 18));
        g.drawString("FPS: " + fps, getWidth() - 90, getHeight() - 10);
		BufferedImage image;
		for (int i = 0 ; i < 11 ; i++ )	{
			for (int x = 0; x < 18 ; x++)	{
				image = (BufferedImage)resourceManager.getAnims().get(String.valueOf(i) + String.valueOf(x));
				g.drawImage(image, (x*32)+5, (i*32)+5, null);
			}
		}
    }
	
	
	
	private class KeyHandler extends KeyAdapter	{
		public void keyPressed(KeyEvent e)	{
			int keyCode = e.getKeyCode();
		}
		public void keyReleased(KeyEvent e)	{
			int keyCode = e.getKeyCode();
			if (keyCode == KeyEvent.VK_M)	{
				if (fullscreen)	{
					windowedMode();
				}
				else	{
					fullscreenMode();
				}
			}
		}
	}
	
}

And I already posted my screen manager.

Well I don’t know what’s causing that behaviour. But make sure its not your own code in the above… you could be pausing the game & never restarting it… that would explain an empty window.

None of that gets called I just realized by adding lots of println lines. It calls activate, opened, deactivated, then it detects my keypress (that triggers the toggle) and no more window events get called. So it isnt a true RunnerApp.

I still haven’t figured out how to reliably switch to full-screen mode midway through the game :P.

There must be something simple we’re doing wrong, maybe someone can lend us some pointers?

I’ve now got full screen mode switching (back & forth, mid-game) working well - the problem for me was the change of bit-depth.

Now I just keep the same bit depth as it was in windowed mode and there’s no problem. I was changing to 16-bit depth and by default my setup is 32. Maybe that will solve it for you too?