如何在Java中的全屏独占模式下处理键盘和鼠标的事件?

在被动呈现模式下,可以使用KeyListenerActionListener接口来处理来自用户的事件。

全屏模式下事件处理的正确方法是什么? 请扩展这个框架,提供鼠标点击和按键事件的实现,请不要臃肿你的例子(例子启动全屏独占模式,使用Timer更新窗口中的graphics):

 import java.applet.Applet; import java.awt.Color; import java.awt.DisplayMode; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferStrategy; import javax.swing.JFrame; import javax.swing.Timer; public class applet extends Applet { Timer timer; JFrame frame; DisplayMode[] displayModes = new DisplayMode[] { new DisplayMode(1280, 800, 32, 60) }; BufferStrategy bufferStrategy; Rectangle bounds; /** * */ private static final long serialVersionUID = 1L; /** * @param args */ public void init() { GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); //displays, fonts, color shemes... GraphicsDevice device = env.getDefaultScreenDevice(); //for one-display systems setIgnoreRepaint(true); GraphicsConfiguration gc = device.getDefaultConfiguration(); frame = new JFrame(gc); device.setFullScreenWindow(frame); if (device.isDisplayChangeSupported()) device.setDisplayMode(displayModes[0]); frame.createBufferStrategy(2); bufferStrategy = frame.getBufferStrategy(); timer = new Timer(1000 / 50, new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { Graphics2D g = null; try { g = (Graphics2D) bufferStrategy.getDrawGraphics(); render(g); } finally { g.dispose(); } bufferStrategy.show(); } }); } private void render(Graphics2D g) { g.setColor(Color.BLACK); g.fillRect(0, 0, bounds.width, bounds.height); } public void start() { timer.start(); } public void stop() { timer.stop(); } } 

它看起来像在如何使用键绑定如何编写一个鼠标监听器全屏独占模式下正常工作。

 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(); } }); } } 

正如这里所build议的,Mac OS X用户对全屏应用程序可能有不同的用户期望。 此处显示的另一种方法依赖于com.apple.eawt类,它提供了一种简单的方法来实现原生function,以便在Mac OS X上微调Java应用程序。 FullScreenUtilities方法setWindowCanFullScreen()启用该function,并且Application方法requestToggleFullScreen()dynamic更改设置。 请注意扩展图标在不同版本中的差异。

Mac OS 10.9,小牛:

10.9

Mac OS 10.10,优胜美地:

10.10

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); } }