Java2D toggle fullscree / windowed.

After reading some guides and books I managed to put together my own screen-manager that implements the Buffer-strategy page-flipping double-buffer. The problem is I would like my game to have the option to toggle between fullscreen and windowed mode but my current screenmanager cannot handle this at all and I am completely lost as to what to do next.

In the example below I draw a string in fullscreen mode, then exit fullscreen mode and the string is gone from my frame. I know this is an active rendering model but do I have to re-render everything when I exit fullscreen (or go fullscreen from windowed)? I do know that I am not actually drawing on the frame, it is just used as a container of sorts and it seems to me that the content of the buffer-strategy is lost when I exit fullscreen.

I know a lot of you are knowledgeable (I have been lurking here since I started java a few months ago) and would appreciate any help as to how to manage this. The end-game is going to be pretty complex with inventory menus, game menus, combatmenus etc and having to actively babysit the bufferstrategy so the content is not lost (by accident or the fullscreen toggle) seems like an immense pain to implement.

Thank you.

package gfx;

import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class ScreenManager {

	private JFrame frame;
	private GraphicsDevice gd;
	private DisplayMode defaultMode;
	private DisplayMode[] supportedModes;
	
	
	// Use with frame from elsewhere
	public ScreenManager(JFrame frame) {
		this();
		this.frame = frame;

	}


	// Used with a frame that is tied to instance
	public ScreenManager() {
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		this.gd = ge.getDefaultScreenDevice();
		this.defaultMode = new DisplayMode(800, 600, 16, 60);
		this.setSupportedModes();
		this.frame = new JFrame();
	}

	// Get the supported displayrates from current graphicsdevice
	private void setSupportedModes() {
		this.supportedModes = gd.getDisplayModes();
	}

	// Check if the supplied displaymode is supported by current device
	public boolean isSupportedDisplayMode(DisplayMode odm) {
		for (DisplayMode dm : this.supportedModes) {
			if (dm.getHeight() == odm.getHeight()
					&& dm.getWidth() == odm.getWidth()
					&& dm.getBitDepth() == odm.getBitDepth()
					|| odm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI
					&& dm.getRefreshRate() == odm.getBitDepth()
					|| odm.getRefreshRate() == DisplayMode.REFRESH_RATE_UNKNOWN)
				return true;

		}
		return false;
	}
	
	public void setFullScreen(DisplayMode displayMode) {
		this.setFullScreen(displayMode, frame);
	}

	// Set fullscreen if supported displaymode, else default displaymode
	public void setFullScreen(DisplayMode displayMode, JFrame frame) {
		if (gd.isFullScreenSupported()) {
			// Fullscreen on visible frame not allowed
			frame.setVisible(false);
			// Remove decoration and unresiable
			frame.setUndecorated(true);
			frame.setResizable(false);
			frame.setIgnoreRepaint(true);
			// Set frame as fullscreenwindow
			gd.setFullScreenWindow(frame);
			// Set default if requested not supported or null
			if (displayMode == null || !isSupportedDisplayMode(displayMode))
				gd.setDisplayMode(defaultMode);

			else
				gd.setDisplayMode(displayMode);
			// Create bufferstrategy
			frame.createBufferStrategy(2);
		}
	}
	
	// Make windowed
	public void setWindowed() {
		// Windowed from fullscreen if fullscreen, otherwise we are probably
		// windowed already
		if (gd.getFullScreenWindow() != null) {
			// gd.getFullScreenWindow().dispose();
			gd.setFullScreenWindow(null);
			// frame.setUndecorated(false);
			frame.setVisible(true);
		}
	}

	// Get the drawing graphics of this ScreenManagers bufferstrategy
	public Graphics2D getGraphics() {
		Window frame = gd.getFullScreenWindow();
		if (frame != null) {
			BufferStrategy bufferStrategy = frame.getBufferStrategy();
			return (Graphics2D) bufferStrategy.getDrawGraphics();
		}
		
		return null;
	}

	public void update() {
		Window frame = gd.getFullScreenWindow();
		if (frame != null) {
			BufferStrategy bufferStrategy = frame.getBufferStrategy();
			if (!bufferStrategy.contentsLost()) 
				bufferStrategy.show();
		}

		Toolkit.getDefaultToolkit().sync();
	}

	// Display in readable format, eg 800x600x32@60
	public String displayModeToString(DisplayMode dm) {
		return dm.getWidth() + "x" + dm.getHeight() + "x" + dm.getBitDepth()
				+ "@" + dm.getRefreshRate();
	}


	public static void main(String[] args) throws InterruptedException {
		JFrame frame = new JFrame();
		frame.setSize(800, 600);
		ScreenManager sm = new ScreenManager(frame);
		sm.setFullScreen(new DisplayMode(1680, 1050, 32, 60));
		Graphics2D g2d = sm.getGraphics();
		g2d.setColor(Color.red);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		Font font = new Font("Serif", Font.PLAIN, 96);
		g2d.setFont(font);
		g2d.drawString("jade", 40, 120);
		g2d.dispose();
		sm.update();
		Thread.sleep(3000);
		sm.setWindowed();


	}


}

You need to redraw everything when you change display mode/size. :slight_smile:

I was hoping to avoid this but if I must I must :smiley:

I was also wondering if bufferedstrategy can be applied to nonfullscreen modes? If I just display stuff on a JFRame, can that JFrame be accelerated with a bufferstrategy even if it is not fullscreen? No direct answer to this on the internet.

Yes, yes you can. :slight_smile:


BufferStrategy bs = this.getBufferStrategy();
if(bs == null) {
	this.createBufferStrategy(2);
	bs = this.getBufferStrategy();
}

Taken from one of my class files that extend JPanel.