Full screen Window won't get keyboard input using KeyListener or KeyBoardFocusManager

前端 未结 2 1282
我寻月下人不归
我寻月下人不归 2021-01-18 04:34

I\'m having problems with getting my KeyBoardFocusManger to work with my full screen Window. No matter what, it just wont get keyboard input. I use

相关标签:
2条回答
  • 2021-01-18 05:02

    Why are you using AWT components in your Swing GUI? I fear (but don't know for sure) that by doing this, you may be losing some of the Swing functionality.

    If you are only capturing select key select key strokes to control the game, consider using Key Bindings.

    Edit:
    No, the AWT components aren't at fault, but still probably should not be used.

    Edit 2:
    Your top level Window is not focused for some reason. Continuing to test code...

    Edit 3:
    Using a JFrame worked for me:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class Test3 {
       public static void main(String[] args) {
          EventQueue.invokeLater(new Runnable() {
    
             @Override
             public void run() {
                GraphicsEnvironment ge = GraphicsEnvironment
                      .getLocalGraphicsEnvironment();
                GraphicsDevice gs = ge.getDefaultScreenDevice();
                if (gs.isFullScreenSupported()) {
                   SpaceInvaderUI spaceInvaderUI = new SpaceInvaderUI(gs.getDefaultConfiguration());
                   gs.setFullScreenWindow(spaceInvaderUI);
                } else {
                   JOptionPane.showMessageDialog(null,
                         "Does not support full screen!", "Error 0x01",
                         JOptionPane.ERROR_MESSAGE);
                   System.exit(1);
                }
             }
          });
       }
    }
    
    // class SpaceInvaderUI extends JWindow {
    class SpaceInvaderUI extends JFrame {
    
       private JPanel drawingPanel;
       private Image background;
       private JButton btnExit;
    
       public SpaceInvaderUI(GraphicsConfiguration gc) {
          super(gc);
          createWindow();
          addKeyBindings();
          setUndecorated(true);
       }
    
       private void addKeyBindings() {
          int condition = JPanel.WHEN_IN_FOCUSED_WINDOW;
          InputMap inputMap = drawingPanel.getInputMap(condition );
          ActionMap actionMap = drawingPanel.getActionMap();
    
          boolean released = false;
          KeyStroke upArrowKeyStrokePressed = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, released );
          String upArrowPressed = "up arrow pressed";
          inputMap.put(upArrowKeyStrokePressed , upArrowPressed);
          actionMap.put(upArrowPressed, new AbstractAction() {
    
             @Override
             public void actionPerformed(ActionEvent arg0) {
                System.out.println("up arrow pressed");
             }
          });
    
          released = true;
          String upArrowReleased = "up arrow released";
          KeyStroke upArrowKeyStrokeReleased = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, released );
          inputMap.put(upArrowKeyStrokeReleased , upArrowReleased);
          actionMap.put(upArrowReleased , new AbstractAction() {
    
             @Override
             public void actionPerformed(ActionEvent arg0) {
                System.out.println("up arrow released");
             }
          });
    
       }
    
       private void createComponents() throws HeadlessException {
          drawingPanel = new DrawingPanel(background, this);
          btnExit = new JButton("Exit");
       }
    
       private void createWindow() {
          createComponents();
          addListeners();
          addComponentsToWindow();
       }
    
       private void addComponentsToWindow() {
          add(drawingPanel, BorderLayout.CENTER);
          add(btnExit, BorderLayout.SOUTH);
       }
    
       private void addListeners() {
    //      KeyboardFocusManager manager = KeyboardFocusManager
    //            .getCurrentKeyboardFocusManager();
    //      manager.addKeyEventDispatcher(new MyDispatcher());
          btnExit.addActionListener(new ActionListener() {
    
             @Override
             public void actionPerformed(ActionEvent ae) {
                System.exit(0);
             }
          });
       }
    //
    //   private class MyDispatcher implements KeyEventDispatcher {
    //
    //      @Override
    //      public boolean dispatchKeyEvent(KeyEvent e) {
    //         System.out.println("in dispatch. KeyEvent := " + e);
    //         if (e.getID() == KeyEvent.KEY_PRESSED) {
    //            System.out.println("pressed");
    //            System.exit(0);
    //         } else if (e.getID() == KeyEvent.KEY_RELEASED) {
    //            System.out.println("released");
    //            System.exit(0);
    //         } else if (e.getID() == KeyEvent.KEY_TYPED) {
    //            System.out.println("Typed");
    //            System.exit(0);
    //         }
    //         return false;
    //      }
    //   }
    }
    
    class DrawingPanel extends JPanel {
    
       private final Image background;
       private final SpaceInvaderUI invaderUI;
    
       DrawingPanel(Image background, SpaceInvaderUI invaderUI) {
          this.background = background;
          this.invaderUI = invaderUI;
          setBackground(Color.pink);
       }
    
       @Override
       protected void paintComponent(Graphics grphcs) {
          super.paintComponent(grphcs);
       }
    }
    
    0 讨论(0)
  • 2021-01-18 05:02

    As shown in this related FullScreenTest, you can use the same Action instance for the button and the key binding.

    Addendum: @nIcE cOw asks, Can we add more than one key on the same JComponent by using InputMap and ActionMap, and use the same AbstractAction class?

    Yes, multiple key bindings are possible; I sometimes invoke doClick() to get the audio-visual feedback, as shown here.

    0 讨论(0)
提交回复
热议问题