2016-11-05 1 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(); 
} 

} 

あなたはペーストビンとして、それを希望の場合は、ここにある:私は初めにSPACE、A、およびDキーを数回(短期および長期プレスを押したときにhttp://pastebin.com/EhPJeAPC

基本的には、何をされて起こります)、 できます。短くて長めのプレスを数回行っただけで、作業が停止します。

誰かが助けることができますか?

EDIT:BTW私は、コードにframe.add()を使用する代わりにframe.getRootPane()が含まれていることを知っています。あなたが望むなら、私はそれを元に戻すことができます。

EDIT:AとDキーの代わりに矢印キーを使用すると、正常に動作することがわかりました。なぜか分からないけど、私はそれに乗って行くつもりです。

+1

(1)そして、何あなたがテストしたときに起こる:あなたはたとえば、より具体的なgetInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)

を使用する必要があり、デフォルトJComponent.WHEN_FOCUSEDマップを、使用するデフォルトgetInputMap()、私のMCVEを使用しています以前の質問であなたに与えられた作業コード???作業コードがすでに与えられているときに、なぜ私たちがあなたのコードをデバッグすることを期待していますか?だから私たちの代わりにあなたのコードをテストする時間を取る。コードをテストする時間がかかります。私たちのコードがうまく動作しない場合は、おそらくバージョン/プラットフォームの問題があります。 – camickr

+0

「矢印キーを使用すれば完璧に動作することが判明しました」 - どのように見つけましたか?最後にあなたに与えられたコードをテストしましたか? – camickr

答えて

1

contentPaneの入力マップが間違っています。

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

関連する問題