0

JPanelsを切り替えると、KeyListenerが応答しない(フォーカスが得られないため)という問題が発生しました。

私はこれをグーグルで行い、この問題を修正するにはKeyBindingsを使用する必要があることを知っていますが、KeyBindingsは好きではありません。だから私は疑問に思っていました、他の方法はありますか?

応答しないKeyListenerを持つJPanelの初期化コードは次のとおりです。

    public void init()
{
    setFocusable(true);
    requestFocusInWindow();
    requestFocus();
    addMouseListener(new MouseInput());
    addMouseMotionListener(new MouseInput());
    addMouseWheelListener(new MouseInput());
    addKeyListener(new KeyInput(p));

    t = new Timer(10, this);
    t.start();
}

必要に応じて、コードサンプルをさらにリクエストしてください。

4

1 に答える 1

6

ハッキーな解決策は、フォーカスがあることを確認するためにを呼び出すことですrequestFocusInWindow()/これは、Componnetが追加された後にのみ呼び出す必要があります(ただし、コンポーネントがフォーカスされていることを確認するために、を介して更新された後に呼び出しました)。JPanelKeyListenerKeyAdapterJFramerevalidate()repaint()

public class MyUI {

    //will switch to the gamepanel by removing all components from the frame and adding GamePanel
    public void switchToGamePanel() {
        frame.getContentPane().removeAll();

        GamePanel gp = new GamePanel();//keylistener/keyadapter was added to Jpanel here

        frame.add(gp);//add component. we could call requestFocusInWindow() after this but to be 98%  sure it works lets call after refreshing JFrame

        //refresh JFrame
        frame.pack();
        frame.revalidate();
        frame.repaint();

        gp.requestFocusInWindow();
    }

}
class GamePanel extends JPanel { 

      public GamePanel() {
          //initiate Jpanel and Keylistener/adapter
      }

}

ただし、Swingを使用する必要がありますKeyBinding(@Reimeusコメントへの+1)。

それらに精通するためにここを読んでください:

これで、明確にするのに役立つ別の例を示すことができます(Oracleは良い仕事をしましたが)

KeyBinding特定のJComponentieJButtonにを追加したい場合は、次のEscようにします。

void addKeyBinding(JComponent jc) {
        jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false), "esc pressed");
        jc.getActionMap().put("esc pressed", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                System.out.println("Esc pressed");
            }
        });

        jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true), "esc released");
        jc.getActionMap().put("esc released", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                System.out.println("Esc released");
            }
        });
}

上記のメソッドは次のように呼び出されます。

JButton b=..;//create an instance of component which is swing

addKeyBinding(b);//add keybinding to the component

ご注意ください:

1)両方は必要ありません。KeyBindings異なるキー状態を取得し、を使用して適切に動作する方法を示しましKeybindingsた。

2)このメソッドは、が押され、コンポーネントがフォーカスのあるウィンドウにあるKeybinding限りアクティブになるを追加します。これは、別の例を指定することで変更できます。EscInputMap

jc.getInputMap(JComponent.WHEN_FOCUSED).put(..);//will only activated when component has focus
于 2012-12-22T18:05:07.017 に答える