JPanelクラスのKeyListenerを使用して矢印キーの1つが押されたときに、何かをしようとしています。これが私のコードです:
public class TestPanel extends JPanel implements KeyListener{
public TestPanel(){
this.addKeyListener(this);
this.setFocusable(true);
this.requestFocusInWindow();
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left");
}
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
}
私のメインメソッドは、このパネルの新しいインスタンスをフレームに追加して表示します。キーリスナーをJFrameに追加する必要がありますか?私の場合、これは難しく非効率的ですので、できればこのJPanelで動作させたいと思います。誰かが私が間違っていることを知っていますか?
編集:どちらも機能しないキーバインディングコード:
public class GamePanel extends JPanel implements ActionListener{
//Constructor
public GamePanel(){
setupKeyBinding();
this.setFocusable(true);
this.requestFocusInWindow();
}
private void setupKeyBinding() {
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inMap = getInputMap(condition);
ActionMap actMap = getActionMap();
inMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left");
actMap.put("Left", new leftAction());
}
private class leftAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
System.out.println("test");
}
}
public void actionPerformed(ActionEvent e) {
//some other game info
}
}
なぜこれも機能しないのか誰かに教えてもらえますか? (私の2番目のアクションリスナーは、私のゲームに必要な他のもののためのものです)
この問題を検索すると、質問され、何度も解決されていることがわかります。
この質問 に対する私の答えを見てください。これについては、多くの厄介な詳細を含めて、詳しく説明しています。
参考までに、私はあなたのアプローチを使用して例を作成しました。それが機能している間、それはまたあなたのコードの他の場所で焦点の問題を示唆します。 キーバインディング 示されているように、これを避けてください ここ 。
補遺:これが私の作業キーバインディングです。
private static class TestPanel extends JPanel {
private static final String LEFT = "Left";
private Action left = new AbstractAction(LEFT) {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(LEFT);
}
};
private static final String RIGHT = "Right";
private Action right = new AbstractAction(RIGHT) {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(RIGHT);
}
};
public TestPanel() {
this.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), LEFT);
this.getActionMap().put(LEFT, left);
this.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), RIGHT);
this.getActionMap().put(RIGHT, right);
}
}
オリジナルのSSCCE:
import Java.awt.EventQueue;
import Java.awt.event.KeyEvent;
import Java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see https://stackoverflow.com/a/16531380/230513
*/
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TestPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class TestPanel extends JPanel implements KeyListener {
public TestPanel() {
this.addKeyListener(this);
this.setFocusable(true);
this.requestFocusInWindow();
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Test().display();
}
});
}
}
JPanel
で重要なイベントを受信するには、フォーカスを設定する必要があります。
setFocusable(true);
requestFocus();
JPanel
にフォーカスがあるため、重要なイベントを受信します
私は2つのことをしなければなりませんでした:comp.setFocusable(true);を追加しました。キーイベントをリッスンするコンポーネントcompに、comp.requestFocus();を追加しました。コンプがフォーカスを失う原因となった各アクションに。