How to handle events from keyboard and mouse in full screen exclusive mode in java?
It looks like the usual approaches shown in How to Use Key Bindings and How to Write a Mouse Listener work correctly in Full-Screen Exclusive Mode.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/** @see http://stackoverflow.com/questions/7456227 */
public class FullScreenTest extends JPanel {
private static final String EXIT = "Exit";
private JFrame f = new JFrame("FullScreenTest");
private Action exit = new AbstractAction(EXIT) {
@Override
public void actionPerformed(ActionEvent e) {
f.dispatchEvent(new WindowEvent(
f, WindowEvent.WINDOW_CLOSING));
}
};
private JButton b = new JButton(exit);
public FullScreenTest() {
this.add(b);
f.getRootPane().setDefaultButton(b);
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), EXIT);
this.getActionMap().put(EXIT, exit);
this.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
FullScreenTest.this.setToolTipText(
"("+ e.getX() + "," + e.getY() + ")");
}
});
}
private void display() {
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice dev = env.getDefaultScreenDevice();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBackground(Color.darkGray);
f.setResizable(false);
f.setUndecorated(true);
f.add(this);
f.pack();
dev.setFullScreenWindow(f);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new FullScreenTest().display();
}
});
}
}
As suggested here, Mac OS X users may have different user expectations for full screen applications. An alternative approach, shown here, relies on com.apple.eawt
classes that "provide a simple way to implement native features to fine tune Java applications on Mac OS X." The FullScreenUtilities
method setWindowCanFullScreen()
enables the feature, and the Application
method requestToggleFullScreen()
changes the setting dynamically. Note how the expand icon differs among versions.
Mac OS 10.9, Mavericks:
Mac OS 10.10, Yosemite:
Mac OS X 10.11, El Capitan:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/**
* @see https://stackoverflow.com/a/30308671/230513
* @see https://stackoverflow.com/questions/7456227
* @see https://stackoverflow.com/q/13064607/230513
* @see https://stackoverflow.com/q/30089804/230513
* @see https://stackoverflow.com/q/25270465/230513
* @see http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/macosx/classes/com/apple/
*/
public class FullScreenTest extends JPanel {
private static final String NAME = "Mac OS X Full Screen Test";
private static final String TOGGLE = "Toggle Full Screen";
private final JFrame f = new JFrame(NAME);
private final Action exit = new AbstractAction(TOGGLE) {
@Override
public void actionPerformed(ActionEvent e) {
toggleOSXFullscreen(f);
}
};
private final JButton b = new JButton(exit);
public FullScreenTest() {
this.add(b);
f.getRootPane().setDefaultButton(b);
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), TOGGLE);
this.getActionMap().put(TOGGLE, exit);
this.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
FullScreenTest.this.setToolTipText(
"(" + e.getX() + "," + e.getY() + ")");
}
});
}
private void display() {
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setBackground(Color.darkGray);
f.add(this);
f.add(new JLabel(NAME, JLabel.CENTER), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
if (System.getProperty("os.name").startsWith("Mac OS X")) {
enableOSXFullscreen(f);
toggleOSXFullscreen(f);
enableOSXQuitStrategy();
}
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println(e);
}
});
}
//FullScreenUtilities.setWindowCanFullScreen(window, true);
private void enableOSXFullscreen(Window window) {
try {
Class util = Class.forName("com.apple.eawt.FullScreenUtilities");
Class params[] = new Class[]{Window.class, Boolean.TYPE};
Method method = util.getMethod("setWindowCanFullScreen", params);
method.invoke(util, window, true);
} catch (ClassNotFoundException | NoSuchMethodException |
SecurityException | IllegalAccessException |
IllegalArgumentException | InvocationTargetException exp) {
exp.printStackTrace(System.err);
}
}
//Application.getApplication().requestToggleFullScreen(window);
private void toggleOSXFullscreen(Window window) {
try {
Class application = Class.forName("com.apple.eawt.Application");
Method getApplication = application.getMethod("getApplication");
Object instance = getApplication.invoke(application);
Method method = application.getMethod("requestToggleFullScreen", Window.class);
method.invoke(instance, window);
} catch (ClassNotFoundException | NoSuchMethodException |
SecurityException | IllegalAccessException |
IllegalArgumentException | InvocationTargetException exp) {
exp.printStackTrace(System.err);
}
}
//Application.getApplication().setQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
private void enableOSXQuitStrategy() {
try {
Class application = Class.forName("com.apple.eawt.Application");
Method getApplication = application.getMethod("getApplication");
Object instance = getApplication.invoke(application);
Class strategy = Class.forName("com.apple.eawt.QuitStrategy");
Enum closeAllWindows = Enum.valueOf(strategy, "CLOSE_ALL_WINDOWS");
Method method = application.getMethod("setQuitStrategy", strategy);
method.invoke(instance, closeAllWindows);
} catch (ClassNotFoundException | NoSuchMethodException |
SecurityException | IllegalAccessException |
IllegalArgumentException | InvocationTargetException exp) {
exp.printStackTrace(System.err);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new FullScreenTest()::display);
}
}