2016-11-05 40 views
-2

我知道我發佈了有關此主題的以前的問題,但我在此發佈一個新問題,因爲我創建了我需要的MCVE。這裏是可以重現問題的類(如果您將此代碼複製並粘貼到您的Java編輯器中(但是要更改包名),那麼它將能夠成功啓動而不會出現任何問題,這是一個完整的測試程序):鍵綁定隨機停止工作,因爲失去焦點也許?

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

} 

如果你想它作爲一個引擎收錄,那就是:http://pastebin.com/EhPJeAPC

基本上,會發生什麼情況是,當我按下SPACE,A和d鍵幾次在開始(短按和長按), 有用。經過幾次短暫和長時間的按壓後,它停止工作!

有人可以幫忙嗎?

編輯:順便說一句,我知道該代碼包括frame.getRootPane()而不是使用frame.add(),但這是因爲我正在嘗試一些東西了。如果你願意,我可以改回它。

編輯:我發現它工作得很好,如果我使用箭頭鍵而不是A和D鍵。我不知道爲什麼,但我會滾動它。

+1

(1)什麼時候你測試發生在你以前的問題中給你的工作代碼?當你已經被賦予工作代碼時,你爲什麼期望我們調試你的代碼?所以不是我們花時間測試你的代碼。你花時間來測試我們的代碼。如果我們的代碼不起作用,那麼可能存在版本/平臺問題。 – camickr

+0

'我發現,如果我使用箭頭鍵,它工作得很好 - - 你是怎麼發現的?你最終測試了以前給你的代碼嗎? – camickr

回答

1

您正在獲取contentPane的錯誤輸入映射。您正在使用的使用默認JComponent.WHEN_FOCUSED地圖,當你應該使用更具體的getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)

例如默認getInputMap(),我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

沒有任何變化。它仍然不起作用... – Blockhead7360

+0

@Blockhead7360:當你嘗試上面的代碼時會發生什麼? –

+0

它仍然做同樣的事情。它起初是有效的,但是當我開始長按按鍵或更快地按下它們時,當我按下按鍵時,它最終會停止發送調試消息。 – Blockhead7360