Full Screen Window Will Not Enter Keyboard Using KeyListener or KeyBoardFocusManager

I am having trouble getting my KeyBoardFocusManger work with my full-screen Window . Regardless, it just wonโ€™t get keyboard input. I used System.exit(0) and println() to search for any method call with pressed / released / printed, but there were no errors. I tried KeyListeners ; but after I read this one , I changed to KeyboardFocusManager and it will happen anyway. I really feel despair; From what can I judge, Window does not focus on the keyboard?

Here is my main one:

 public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { // Determine if full-screen mode is supported directly GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gs = ge.getDefaultScreenDevice(); if (gs.isFullScreenSupported()) { Frame frame = new Frame(gs.getDefaultConfiguration()); SpaceInvaderUI spaceInvaderUI = new SpaceInvaderUI(frame); // Enter full-screen mode gs.setFullScreenWindow(spaceInvaderUI); } else { JOptionPane.showMessageDialog(null, "Does not support full screen!", "Error 0x01", JOptionPane.ERROR_MESSAGE); System.exit(1); } } }); } 

and here is the user interface that contains KeyBoardFocusManger , and is added to the addListeners() method:

 class SpaceInvaderUI extends Window { private JPanel drawingPanel; private Image background; private JButton btnExit; public SpaceInvaderUI(Frame frame) { super(frame); try { background = ImageIO.read(getClass().getResourceAsStream("background.png")); } catch (Exception ex) { JOptionPane.showMessageDialog(null, "Could not extract resource: " + ex.getMessage(), "Error 0x02", JOptionPane.ERROR_MESSAGE); System.exit(2); } createWindow(); } 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) { 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; } } } 

The exit button is only because I'm tired of killing my application using the task manager. Finally, here is my panel on which the game will be played, and my background is painted on:

 public class DrawingPanel extends JPanel { private final Image background; private final SpaceInvaderUI invaderUI; DrawingPanel(Image background, SpaceInvaderUI invaderUI) { this.background = background; this.invaderUI = invaderUI; } @Override protected void paintComponent(Graphics grphcs) { super.paintComponent(grphcs); grphcs.drawImage(background.getScaledInstance((int) invaderUI.getWidth(), (int) invaderUI.getHeight(), Image.SCALE_SMOOTH), 0, 0, this); } } 

Thanks in advance.

EDIT: now I tried using the key binding on my drawingPanel , but nothing happens when I press f2:

 class SpaceInvaderUI extends Window { private JPanel drawingPanel; private Image background; private JButton btnExit; public SpaceInvaderUI(Frame frame) { super(frame); try { background = ImageIO.read(getClass().getResourceAsStream("background.png")); } catch (Exception ex) { JOptionPane.showMessageDialog(null, "Could not extract resource: " + ex.getMessage(), "Error 0x02", JOptionPane.ERROR_MESSAGE); System.exit(2); } createWindow(); } 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() { Action exit = new AbstractAction() { public void actionPerformed(ActionEvent e) { System.exit(0); } }; drawingPanel.getInputMap().put(KeyStroke.getKeyStroke("F2"), exit); btnExit.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { System.exit(0); } }); } } 
+7
source share
2 answers

Why are you using AWT components in your Swing GUI? I am afraid (but I donโ€™t know for sure) that by doing this you might lose some Swing features.

If you just lock the selected keys, select key strokes to control the game, consider using key bindings .

Edit :
No, AWT components are not wrong, but probably should not be used.

Edit 2 :
For some reason, your top-level window is not focused. Continuing code verification ...

Edit 3 :
Using 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); } } 
+5
source

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

Addendum: @nIcE cOw asks: can we add more than one key to the same JComponent using InputMap and ActionMap and use the same AbstractAction class?

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

+4
source

All Articles