My Java app uses two JFrames - the first one to present a choice to the user from a limited number of options (no full screen), and the second to present the data (with the full screen option).
I was using setVisible() to switch between my two frames which was good because it reused the previous Virtual Desktop and retained the full screen mode, but I had to switch to dispose() in order to hide the second JFrame because of a toolkit thread paint problem.
When I go into full screen mode in frame2, a new virtual desktop is created - but if I dispose frame2, that VD still exists as an empty grey desktop. Having disposed() it to return to frame1, if I then switch back again to frame2 we are no longer in full screen... and if I do... then I now have 2 virtual desktops. And so on.
Using setVisible(false) on frame2 also leaves the empty virtual desktop in place, although that is less of a problem than the repaint/buffer issue, as the next time I setVisible(true) on frame2 at least it opens up in the same VD, as I mentioned above.
My question is: can I save and restore the full screen mode in frame2 using the same VD after a dispose(), or can I at least force the VD to close? Or have I missed another solution to the problem? Or is this simply because I'm not strict following Apple's full screen guidelines?!
Thank you in advance for any help.
UPDATE: I went back to using setVisible(false) to hide frame2, but using new() each time I display it (to avoid repaint/buffer problem), and again I have the same duplicate VD problem. I also implemented com.apple.eawt.Application.requestToggleFullScreen along with com.apple.eawt.FullScreenListener to quit full screen before I dispose, but the app hangs. Now looks like I'll have to live with the repaint.buffer issue to allow full screen switching to work correctly.
SSCCE:
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SwingFramesFullScreenMacDemo extends javax.swing.JFrame {
JFrame secondFrame;
JPanel myPanel;
public SwingFramesFullScreenMacDemo() {
//Setup UI With Button to show secondFrame
JPanel thisPanel = new JPanel();
JButton jbtOpenFullScreenFrame = new JButton("Open Full Screen Frame");
jbtOpenFullScreenFrame.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
secondFrame.setVisible(true);
setVisible(false);
}
});
thisPanel.add(jbtOpenFullScreenFrame);
this.add(thisPanel);
this.pack();
// Setup Second Frame With Full Screen Support
secondFrame = new JFrame();
myPanel = new JPanel();
//Dispose() works without residual image, but leaves open virtual desktop for each time
//you go to full screen then dispose
JButton jbtDispose = new JButton("Dispose");
jbtDispose.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(true);
secondFrame.dispose();
}
});
//SetVisible(false) gives residual image on reopening second frame despite clearing colour
//works well for fullscreen, only one virtual desktop open for lifetime of app
JButton jbtSetVisibleFalse = new JButton("Set Visible to False");
jbtSetVisibleFalse.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
secondFrame.setVisible(false);
setVisible(true);
}
});
myPanel.add(jbtDispose);
myPanel.add(jbtSetVisibleFalse);
secondFrame.add(myPanel);
secondFrame.pack();
enableFullScreenMode(secondFrame);
secondFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
setVisible(true);
secondFrame.setVisible(false);
}
});
}
public static void enableFullScreenMode(Window window) {
String methodName = "setWindowCanFullScreen";
try {
Class<?> clazz = Class.forName(com.apple.eawt.FullScreenUtilities.class.getName());
Method method = clazz.getMethod(methodName, new Class<?>[]{
Window.class, boolean.class});
method.invoke(null, window, true);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException t) {
System.err.println("Full screen mode is not supported");
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
javax.swing.JFrame fullScreenMacProblem = new SwingFramesFullScreenMacDemo();
fullScreenMacProblem.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
fullScreenMacProblem.setVisible(true);
}
});
}
}