2017-02-13 19 views
0

NetBeansでjframeを作成しましたが、このjframeは別のJavaクラスによって「起動」されていますが、現在の質問には関係ありません。重要なことは、私のこのjframeにキーリスナーを追加する方法を見つけることができないという事実です。私はキーリスナーを実装し、必要な機能(キー入力、キー押下、キーリリース)を追加しました。しかし、実際のキー・リスナーを実際に追加/開始して動作させる方法を理解することはできません。JframeにKeyListenerを追加する

現時点では、実際には実際のフレームが開始されているコードの先頭にaddKeylistener(new JFrameList());という行を追加しようとしましたが、実際のフレームでも表示されません。これとは別に、同じ行を別の関数callJframFForm()に追加しようとしましたが、これはjframeが呼び出されるのと同時に別のクラスから呼び出されます。しかし、これはエラーnon-static method addKeyListener(KeyListener) cannot be referenced from a static contextを返します。私は、キーリスナーを追加することができる他の方法が何であるか分かりませんので、ちょっとした助けを求めています。

現在、私のコードは以下のようになります。

import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

public class JFrameList extends javax.swing.JFrame implements KeyListener{ 

    public static String keyPresCod = ""; 

    public JFrameList() { 
     initComponents(); 
     addKeyListener(new JFrameList()); //This is where I am currently trying to call from, but frame won't show 
    }  

    public static void main(String args[]) { 
     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new JFrameList().setVisible(true); 
      } 
     }); 
    }             

    // Variables declaration - do not modify      
    private javax.swing.JButton jButton1; 
    private javax.swing.JButton jButton2; 
    private javax.swing.JLabel jLabel1; 
    private javax.swing.JLabel jLabel2; 
    // End of variables declaration     

    static void callJframFForm(){ 
     try { 
      //This is where I have also tried to add the initialization line 
     } catch(Exception e) { 
      e.printStackTrace(); 
    } 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     int codeFKey = e.getKeyCode(); 

     if (codeFKey == KeyEvent.VK_A) { 
      System.out.println("Button A clicked"); 
         keyPresCod = "A"; 
     } else if (codeFKey == KeyEvent.VK_B) { 
      System.out.println("Button B clicked"); 
         keyPresCod = "B"; 
     } else { 
      System.out.println("Different key pressed"); 
         keyPresCod = "Another key"; 
     } 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 

    } 

    @Override 
    public void keyReleased(KeyEvent e) { 

    } 

} 
+0

あなたの現在のアプローチは過度であると思います。[ボタン、チェックボックス、ラジオボタンの使い方]を参照してください(http://docs.oracle.com/javase/tutorial/uiswing/components/ button.html)は、ユーザーが使用しているあらかじめ定義された作業方法を持っています。 – MadProgrammer

+1

@MadProgrammer - '私は見ています... ' - うれしいです。 – camickr

+0

@camickrしかし、OPが解決しようとしている問題への文脈の欠如を考えると、私はそれが答えかどうかわかりません;) – MadProgrammer

答えて

1

問題

addKeyListener(new JFrameList()) 

は、これは新しいJFrameListオブジェクトを作成し、それがリスナーの使用しています。これは、新しいオブジェクトのメンバにキーストロークが格納されていることを意味します。結果を確認するには、実行する必要があります。

JFrameList list = new JFrameList(); addKeyListener(list); //リスト変数を使用してkeyPressedコードにアクセスする

もちろん、これは必要な動作ではありません。キーストロークを新しいオブジェクトではなく、現在のインスタンスに格納する必要があります。あなたがリスナーに気づくかもしれないが、これはあなたが

addKeyListener(this) 

をやるべきことを意味のみ「時々」作品、またはそうでないかもしれないすべてであなたがそれをテストしているかによって異なります。

スイングはフォーカスを使用してイベントを受け取るリスナーを管理し、リスナーをJFrameに追加するので、リスナーはフォーカスが当たっているときだけイベントを受信します。

ソリューション

あなたがすべきuse key bindings rather than a key listener

リスナーを引き続き使用することを選択した場合、あなたがボタンに追加すべきではなく、あなたのフレーム:

jButton1.addKeyListener(this); 
jButton2.addKeyListener(this); 

代わりにイベントのキーコードを確認するには、イベントのソースをつかむことができ(あなたのボタン)をevent.getSource()に呼んでください。

キーバインドでは、コンポーネントに柔軟なフォーカス設定を設定できます。それはアクションとして、あなたのイベントを受信するように、

String actionCommand = "Press Button A"; 
jButton1.setActionCommand(actionCommand); 
jButton1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), actionCommand); 
jButton1.getActionMap(actionCommand, this); 

あなたJFrameListは今KeyListenerActionListenerを実装するのではなくする必要があります:あなたがする必要があるのは、コンポーネントの入力マップにアクセスしている

class JFrameList extends JFrame implements ActionListener { 
    private JButton jButton1; 

    public JFrameList() { 
     jButton1 = new JButton("A"); 
     //set action command, add to input map, add to action map 
    } 

    public void actionPerformed(ActionEvent event) { 
     JButton button = (JButton) event.getSource(); 
     System.out.println(button.getActionCommand() + " was performed."); 
    } 
} 

代替

JButtonには、ニーモニック処理が組み込まれています。

jButton1.setMnemonic(KeyEvent.VK_A); 

これは、グラフィカルインタフェースでホットキーを処理する標準的な方法です:あなたは、引数がキーコードであるJButton#setMnemonic(int)、経由ニーモニックを指定することができます。単にAltキー(Windows)を押しながら、ニーモニックを設定するキーを押してください。

+0

私は本当に入力していただきありがとうございます。私は、開始時に初期化関数内に 'addKeyListener(this)'という行を持つようにコードを変更しました。今度はJframeが再び表示されますが、実際のキーリスナーは機能していないようです。ご覧のように、クリックされたボタンに応じて特定のものを印刷するように設定されています。しかし、それはしません。 –

+0

@ rootsquaredtimes89これは、リスナーがフレームに追加されているため、イベントをディスパッチするためにフレームにフォーカスが必要なためです。表示された後、フレーム 'requestFocus'を持つことができますが、ボタンをクリックしたときなど、フレームをクリックするとすぐにフォーカスが失われます。私は自分の答えを更新しました –

+0

'KeyListener'をボタンに追加すると、ボタンがフォーカスを得るまで応答しないので、キーバインディングは' KeyListener'の問題を克服する正しい解決策ですが、ボタンは似たような仕事をすることができる機能が組み込まれています – MadProgrammer

0

キーイベントは、フォーカスのあるコンポーネントにのみディスパッチされます。あなたはコード全体を投稿しませんでしたが、そのフォーカスがフレームに追加するボタンにあると推測しています。ボタンがKeyEventを取得します。

KeyListenerで何をしようとしているのか不明です。どのボタンがクリックされたのかは、KeyEventに入力された文字を見ることでわかりません。

クリックされたボタンを知りたい場合は、各ボタンにActionListenerを追加する必要があります。詳しくは、How to Use ButtonsのSwingチュートリアルのセクションを読んでください。

関連する問題