How to handle events from keyboard and mouse in fu

2018-12-31 06:20发布

In passive rendering mode one can use KeyListener and ActionListener interfaces to handle events from user.

What is the correct way of event handling in full screen mode? Please extend this skeleton providing implementation for mouse click and key press events, please don't bloat your example (the example starts full screen exclusive mode, using a Timer to update graphics in window):

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

}

2条回答
呛了眼睛熬了心
2楼-- · 2018-12-31 07:10

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();
            }
        });
    }
}
查看更多
君临天下
3楼-- · 2018-12-31 07:16

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:

10.9

Mac OS 10.10, Yosemite:

10.10

Mac OS X 10.11, El Capitan:

enter image description here

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);
    }
}
查看更多
登录 后发表回答