java keylistener non appelé

J’ai écrit un exemple de code à l’aide de KeyListener en Java, j’ai créé un JPanel , puis défini son focus sur true, j’ai créé un KeyListener, demandé un focus, puis ajouté le KeyListener à mon panneau. Mais les méthodes pour keyListener ne sont jamais appelées. Il semble que même si j’ai demandé la concentration, cela ne se concentre pas.

Quelqu’un peut-il aider?

 listener = new KeyLis(); this.setFocusable(true); this.requestFocus(); this.addKeyListener(listener); class KeyLis implements KeyListener{ @Override public void keyPressed(KeyEvent e) { currentver += 5; switch (e.getKeyCode()) { case KeyEvent.VK_LEFT : if(horizontalyInBounds()) currentPos-= 5; break; case KeyEvent.VK_RIGHT: if(horizontalyInBounds()) currentPos+= 5; break; } repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { } } 

Si un code exécutable est nécessaire:

  import java.awt.Color; import java.awt.Graphics; import java.util.Random; import javax.swing.JFrame; import javax.swing.JLabel; public class test extends JFrame { private AreaOfGame areaOfGame; public test() { super(""); setVisible(true); this.setBackground(Color.darkGray); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); setLayout(null); setBounds(200, 10, 400, 700); areaOfGame = new AreaOfGame(); this.add(areaOfGame); startGame(); } public int generateNext() { Random r = new Random(); int n = r.nextInt(7); return n; } public void startGame() { while(!areaOfGame.GameOver()) { areaOfGame.startGame(generateNext()); } } public static void main(Ssortingng[] args) { new MainFrame(); } import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.swing.JPanel; public class AreaOfGame extends JPanel { private static final int rightside = 370; private int bottom; private int top; private int currentPos; private int currentver; private KeyLis listener; public AreaOfGame() { super(); bottom = 650; top = 50; setLayout(null); setBounds(20, 50, 350, 600); setVisible(true); this.setBackground(Color.lightGray); listener = new KeyLis(); this.setFocusable(true); if(this.requestFocus(true)) System.out.println("true");; this.addKeyListener(listener); currentPos = 150; currentver=0; } public void startGame(int n) { while(verticallyInBound()){ System.out.println("anything"); } } public boolean verticallyInBound() { if(currentPos= bottom){ System.out.println("game over"); return true; } else return false; } public boolean horizontalyInBounds() { if(currentPos= 20) return true; else return false; } class KeyLis implements KeyListener{ @Override public void keyPressed(KeyEvent e) { System.out.println("called"); currentver += 5; switch (e.getKeyCode()) { case KeyEvent.VK_LEFT : if(horizontalyInBounds()) currentPos-= 5; break; case KeyEvent.VK_RIGHT: if(horizontalyInBounds()) currentPos+= 5; break; } repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { System.out.println("called 3"); } } } 

Je parie que vous demandez le focus avant que le JPanel ait été restitué (avant que la fenêtre de niveau supérieur n’ait appelé pack() ou setVisible(true) ), et si c’est le cas, cela ne fonctionnera pas. La demande de focus ne sera éventuellement accordée qu’une fois les composants rendus. Avez-vous vérifié ce que votre appel à requestFocus() a renvoyé? Pour que votre appel ait la moindre chance de réussir, il doit être vrai. De plus, il est préférable d’utiliser requestFocusInWindow() plutôt que requestFocus() .

Mais plus important encore, vous ne devriez pas utiliser KeyListeners pour cela, mais plutôt des liaisons de clé, un concept de niveau supérieur que Swing lui-même utilise pour répondre aux pressions sur les touches.

modifier
Un exemple de SSCCE :

 import java.awt.Dimension; import java.awt.event.*; import javax.swing.*; public class TestKeyListener extends JPanel { private KeyLis listener; public TestKeyListener() { add(new JButton("Foo")); // something to draw off focus listener = new KeyLis(); this.setFocusable(true); this.requestFocus(); this.addKeyListener(listener); } @Override public Dimension getPreferredSize() { return new Dimension(300, 200); } private class KeyLis extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: System.out.println("VK_LEFT pressed"); break; case KeyEvent.VK_RIGHT: System.out.println("VK_RIGHT pressed"); break; } } } private static void createAndShowGui() { TestKeyListener mainPanel = new TestKeyListener(); JFrame frame = new JFrame("TestKeyListener"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(Ssortingng[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } 

Modifier 2
Et le SSCCE équivalent utilisant des raccourcis clavier:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class TestKeyBindings extends JPanel { public TestKeyBindings() { add(new JButton("Foo")); // something to draw off focus setKeyBindings(); } private void setKeyBindings() { ActionMap actionMap = getActionMap(); int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inputMap = getInputMap(condition ); Ssortingng vkLeft = "VK_LEFT"; Ssortingng vkRight = "VK_RIGHT"; inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), vkLeft); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), vkRight); actionMap.put(vkLeft, new KeyAction(vkLeft)); actionMap.put(vkRight, new KeyAction(vkRight)); } @Override public Dimension getPreferredSize() { return new Dimension(300, 200); } private class KeyAction extends AbstractAction { public KeyAction(Ssortingng actionCommand) { putValue(ACTION_COMMAND_KEY, actionCommand); } @Override public void actionPerformed(ActionEvent actionEvt) { System.out.println(actionEvt.getActionCommand() + " pressed"); } } private static void createAndShowGui() { TestKeyBindings mainPanel = new TestKeyBindings(); JFrame frame = new JFrame("TestKeyListener"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(Ssortingng[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } 

Modifier 3
En ce qui concerne votre SSCCE récent, vos boucles while (true) bloquent votre thread d’événement Swing et peuvent empêcher l’interaction de l’utilisateur ou la mise en peinture. Mieux vaut utiliser un minuteur Swing plutôt que while (true) . Par exemple:

 import java.awt.*; import java.awt.event.*; import java.util.Random; import javax.swing.*; public class BbbTest extends JFrame { private AreaOfGame areaOfGame; public BbbTest() { super(""); // setVisible(true); this.setBackground(Color.darkGray); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); setLayout(null); setBounds(200, 10, 400, 700); areaOfGame = new AreaOfGame(); this.add(areaOfGame); setVisible(true); startGame(); } public int generateNext() { Random r = new Random(); int n = r.nextInt(7); return n; } public void startGame() { // while (!areaOfGame.GameOver()) { // areaOfGame.startGame(generateNext()); // } areaOfGame.startGame(generateNext()); } public static void main(Ssortingng[] args) { new BbbTest(); } class AreaOfGame extends JPanel { private static final int rightside = 370; private int bottom; private int top; private int currentPos; private int currentver; private KeyLis listener; public AreaOfGame() { super(); bottom = 650; top = 50; setLayout(null); setBounds(20, 50, 350, 600); setVisible(true); this.setBackground(Color.lightGray); listener = new KeyLis(); this.setFocusable(true); if (this.requestFocus(true)) System.out.println("true"); ; this.addKeyListener(listener); currentPos = 150; currentver = 0; } public void startGame(int n) { // while (verticallyInBound()) { // System.out.println("anything"); // } int timeDelay = 50; // msecs delay new Timer(timeDelay , new ActionListener() { public void actionPerformed(ActionEvent arg0) { System.out.println("anything"); } }).start(); } public boolean verticallyInBound() { if (currentPos <= bottom - 50) return true; return false; } public boolean GameOver() { if (top >= bottom) { System.out.println("game over"); return true; } else return false; } public boolean horizontalyInBounds() { if (currentPos <= rightside && currentPos >= 20) return true; else return false; } class KeyLis implements KeyListener { @Override public void keyPressed(KeyEvent e) { System.out.println("called"); currentver += 5; switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: if (horizontalyInBounds()) currentPos -= 5; break; case KeyEvent.VK_RIGHT: if (horizontalyInBounds()) currentPos += 5; break; } repaint(); } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent e) { System.out.println("called 3"); } } } } 

Il est possible d’utiliser le bouton “TAB” pour basculer entre les boutons et l’écouteur. J’ai un programme avec un bouton qui après que j’appuie dessus, le programme d’écoute ne fonctionne pas. Je me suis rendu compte que si vous appuyez sur le bouton “TAB”, le “Attention” ou “focus” du programme revient à l’écouteur clé.

peut-être que cela aidera: http://docstore.mik.ua/orelly/java-ent/jfc/ch03_08.htm