2011-09-17 18 views
11

在被動渲染模式下,可以使用接口KeyListenerActionListener來處理來自用戶的事件。如何在Java中以全屏獨佔模式處理來自鍵盤和鼠標的事件?

在全屏模式下事件處理的正確方法是什麼?請擴展此框架提供實現鼠標點擊按鍵事件,請不要臃腫的例子(例子開始全屏獨佔模式,使用Timer更新窗口圖形):

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

} 

回答

22

它看起來像How to Use Key BindingsHow to Write a Mouse Listener中顯示的通常方法在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(); 
      } 
     }); 
    } 
} 
+0

謝謝你的回答!你能不能也請提供相同的例子,但作爲Java小程序?我想要成爲一個Java小程序的例子,但似乎我忘了在第一篇文章中包含它...我認爲你只需要對你提供的實際代碼進行小的增加/更改,非常感謝你,如果你這樣做,因爲你的例子很好學習! – Vadim

+2

我建議'JApplet',但爲了安全起見,它可能必須[signed](http://download.oracle.com/javase/tutorial/deployment/applet/security.html)。您可以使用[此處]顯示的混合方法進行試用(https://sites.google.com/site/drjohnbmatthews/subway); [tag:java-web-start]會是一個更好的部署策略。 – trashgod

+0

謝謝,會檢查它! – Vadim

7

至於建議here,Mac OS X用戶可以對全屏應用的不同用戶的期望。另一種方法,如here所示,依賴於com.apple.eawt類,它們「提供了一種簡單的方法來實現原生功能,以微調Mac OS X上的Java應用程序」。 FullScreenUtilities方法setWindowCanFullScreen()啓用該功能,並且Application方法requestToggleFullScreen()動態更改設置。請注意0​​之間展開圖標的差異。

的Mac OS 10.9,小牛:

10.9

的Mac OS 10.10,優勝美地:

10.10

的Mac OS X 10.11,埃爾卡皮坦:

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

另請參見[* OSX上的Swing:如何捕獲command-Q?*](http://stackoverflow.com/q/2061194/230513) – trashgod

+0

快速提示:對'requestToggleFullScreen'的調用似乎在默認情況下會失敗在[可顯示]框架之前(https://docs.oracle.com/javase/8/docs/api/java/awt/Component.html#isDisplayable--)。 (測試El Capitan 10.11.6。) – Radiodef