I’ve got my post snippet above working too.
It seems there are still 2 bugs present in the disposing of Frames.
-
This is the bug exposed by my previous code snippet.
If you dispose of a window before it has EVER been made displayable, it will die the second time you try and go into fullscreen mode.
i.e.
APP. START
dispose
goto Windowed
dispose
goto Fullscreen
dispose
goto Windowed
dispose
goto Fullscreen causes APP. DEATH
I fixed the problem above, by wrapping the dispose() in an ‘if(isDisplayable())’ so the initial call to dispose() is avoided.
This fixes the crash experienced above… however.
-
It appears that calling dispose() on a window that is currently in fullscreen exclusive mode is still abit ‘iffy’.
Occasionally when going from fullscreen to windowed mode, it will fail to restore the desktop resolution.
This can be fixed by adding a setFullscreenWindow(null), before calling dispose().
It so happens that the fix for problem 2) also fixes the problem experienced in 1), so the ‘if(isDisplayable())’ wrapping around dispose() can be eliminated.
Doing this leaves the code below as the absolute bare minimum that will successfully switch fullscreen<->windowed on my machine.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class FullscreenSwitchTest extends Frame implements KeyListener
{
volatile boolean change = true;
volatile boolean running = true;
public void keyPressed(KeyEvent ke)
{
if(ke.getKeyCode()==KeyEvent.VK_ESCAPE)
{
change = false;
running = false;
}
else
{
change = true;
}
}
public void keyReleased(KeyEvent ke){}
public void keyTyped(KeyEvent ke){}
public FullscreenSwitchTest()
{
boolean fullscreen = true;
addKeyListener(this);
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
while(running)
{
if(change)
{
fullscreen=!fullscreen;
gd.setFullScreenWindow(null);//this line fixes 2 bugs.
dispose();
setUndecorated(fullscreen);
if(fullscreen)
{
gd.setFullScreenWindow(this);
gd.setDisplayMode(new DisplayMode(800,600,32,0));
}
else
{
setBounds(0,0,800,600);
setVisible(true);
}
change = false;
}
}
}
public static void main(String [] args)
{
new FullscreenSwitchTest();
}
}