2016-11-05 2 views
-2

Ich weiß, dass ich vorhergehende Fragen zu diesem Thema gestellt habe, aber ich poste hier einen neuen, weil ich den MCVE erstellt habe, den ich brauchte. Hier ist die Klasse, die das Problem reproduzieren kann (wenn Sie diesen Code in Ihren Java-Editor kopieren und einfügen (aber den Paketnamen ändern), dann kann er ohne Probleme erfolgreich gestartet werden. Dies ist ein vollständiges Testprogramm):Keybindings hören zufällig auf zu arbeiten, weil der Fokus vielleicht verloren geht?

package com.blockhead7360.test.ppa; 

import java.awt.Dimension; 
import java.awt.event.ActionEvent; 

import javax.swing.AbstractAction; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JTextArea; 
import javax.swing.KeyStroke; 

public class TotalKeyTest { 

static JTextArea area; 

static int i = 0; 

public TotalKeyTest(){ 
    JFrame frame = new JFrame("Test"); 
    frame.setPreferredSize(new Dimension(600, 600)); 
    frame.setMaximumSize(new Dimension(600, 600)); 
    frame.setMinimumSize(new Dimension(600, 600)); 

    JComponent comp = (JComponent) frame.getContentPane(); 
    frame.getRootPane().getRootPane().setActionMap(bindKeys(comp).getActionMap()); 
    frame.getRootPane().getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, bindKeys(comp).getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)); 
    frame.pack(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setResizable(false); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true);   

} 

public static JComponent bindKeys(JComponent comp){ 
    comp.getInputMap().put(KeyStroke.getKeyStroke("pressed SPACE"), "pressSpace"); 
    comp.getActionMap().put("pressSpace", new AbstractAction(){ 

     private static final long serialVersionUID = 1L; 

     public void actionPerformed(ActionEvent e){ 
      System.out.println("pressed Space"); 
     } 
    }); 

    comp.getInputMap().put(KeyStroke.getKeyStroke("pressed A"), "pressLeft"); 
    comp.getActionMap().put("pressLeft", new AbstractAction(){ 

     private static final long serialVersionUID = 1L; 

     public void actionPerformed(ActionEvent e){ 
      System.out.println("pressed left"); 
     } 
    }); 
    comp.getInputMap().put(KeyStroke.getKeyStroke("released A"), "releaseLeft"); 
    comp.getActionMap().put("releaseLeft", new AbstractAction(){ 

     private static final long serialVersionUID = 1L; 

     public void actionPerformed(ActionEvent e){ 
      System.out.println("released left"); 
     } 
    }); 

    comp.getInputMap().put(KeyStroke.getKeyStroke("D"), "pressRight"); 
    comp.getActionMap().put("pressRight", new AbstractAction(){ 

     private static final long serialVersionUID = 1L; 

     public void actionPerformed(ActionEvent e){ 
      System.out.println("pressed right"); 
     } 
    }); 
    comp.getInputMap().put(KeyStroke.getKeyStroke("released D"), "releaseRight"); 
    comp.getActionMap().put("releaseRight", new AbstractAction(){ 

     private static final long serialVersionUID = 1L; 

     public void actionPerformed(ActionEvent e){ 
      System.out.println("released right"); 
     } 
    }); 
    return comp; 

} 

public static void main(String args[]){ 
    new TotalKeyTest(); 
} 

} 

Wenn Sie es als ein Pastebin möchte, hier ist es: http://pastebin.com/EhPJeAPC

im Grunde, was passiert ist, wenn ich drücken Sie die SPACE, A und D-Tasten ein paar mal am Anfang (kurz und lang drückt), Es klappt. Nach ein paar kurzen und langen Drücken hört es einfach auf zu arbeiten!

Kann jemand helfen?

BEARBEITEN: BTW Ich weiß, dass der Code enthält die frame.getRootPane() statt nur mit frame.add(), aber das war da, weil ich einige Sachen ausprobiert. Ich kann es zurück ändern, wenn Sie wollen.

EDIT: Ich fand heraus, dass es völlig in Ordnung ist, wenn ich die Pfeiltasten statt der A und D-Tasten verwende. Ich weiß nicht warum, aber ich werde damit spielen.

+1

(1-) Und was passiert, wenn Sie den Test Arbeitscode, der dir in deiner vorherigen Frage gegeben wurde ??? Warum erwarten Sie, dass wir Ihren Code debuggen, wenn Ihnen bereits funktionierender Code zur Verfügung steht? Also nehmen wir uns Zeit, um Ihren Code zu testen. Sie nehmen sich die Zeit, unseren Code zu testen. Wenn unser Code nicht funktioniert, dann gibt es vielleicht ein Versions/Plattform Problem. – camickr

+0

'Ich fand heraus, dass es vollkommen in Ordnung ist, wenn ich die Pfeiltasten benutze' - wie hast du das herausgefunden? Hast du den Code, der dir zuvor gegeben wurde, endlich getestet? – camickr

Antwort

1

Sie erhalten die falsche Eingabekarte für den contentPane. Sie verwenden die Standard-getInputMap(), die die Standard-JComponent.WHEN_FOCUSED Karte verwendet, wenn Sie getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)

Zum Beispiel des speziellere verwenden sollen, meine MCVE:

import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class TotalKeyTest2 extends JPanel { 
    private static final int PREF_W = 600; 
    private static final int PREF_H = PREF_W; 
    private int condition = WHEN_IN_FOCUSED_WINDOW; 
    private InputMap inputMap = getInputMap(condition); 
    private ActionMap actionMap = getActionMap(); 

    public TotalKeyTest2() { 
     setBindings(); 
    } 

    private void setBindings() {   
     insertKey(KeyEvent.VK_SPACE, "Space"); 
     insertKey(KeyEvent.VK_A, "Left"); 
     insertKey(KeyEvent.VK_D, "Right"); 
    } 

    private void insertKey(int keyCode, String text) { 
     KeyStroke pressed = KeyStroke.getKeyStroke(keyCode, 0, false); 
     KeyStroke released = KeyStroke.getKeyStroke(keyCode, 0, true); 
     String pressedActionName = text + " Pressed"; 
     String releasedActionName = text + " Released"; 
     Action pressedAction = new MyAction(pressedActionName); 
     Action releasedAction = new MyAction(releasedActionName);   
     inputMap.put(pressed, pressedActionName); 
     inputMap.put(released, releasedActionName); 
     actionMap.put(pressedActionName, pressedAction); 
     actionMap.put(releasedActionName, releasedAction); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class MyAction extends AbstractAction { 

     public MyAction(String name) { 
      super(name); 
     } 


     @Override 
     public void actionPerformed(ActionEvent e) { 
      System.out.println(getValue(NAME)); 
     } 
    } 

    private static void createAndShowGui() { 
     TotalKeyTest2 mainPanel = new TotalKeyTest2(); 

     JFrame frame = new JFrame("TotalKeyTest2"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 
+0

Nichts hat sich geändert. Es funktioniert immer noch nicht ... – Blockhead7360

+0

@ Blockhead7360: Was passiert, wenn Sie den obigen Code versuchen? –

+0

Es macht immer noch das Gleiche. Es funktioniert zuerst, aber nachdem ich anfange, die Tasten lang zu drücken oder sie schneller zu drücken, hört es schließlich auf, die Debug-Nachrichten zu senden, wenn ich die Schlüssel drücke. – Blockhead7360

Verwandte Themen