2011-12-12 8 views
7

KeyListenerをJavaで使用して、 を作成しました。JPanelを作成し、そのフォーカスをtrueに設定しました。私はKeyListenerを作成し、フォーカスを要求してからKeyListenerをパネルに追加しました。しかし、keyListenerのメソッドは決して呼び出されません。私は焦点を要求したようだが、それは焦点を当てていないようだ。java keylistenerが呼び出されていない

誰でも手助けできますか?

listener = new KeyLis(); 
this.setFocusable(true); 
this.requestFocus(); 
this.addKeyListener(listener); 

class KeyLis implements KeyListener{ 

    @Override 
    public void keyPressed(KeyEvent e) { 
     currentver += 5; 
     switch (e.getKeyCode()) { 
      case KeyEvent.VK_LEFT : if(horizontalyInBounds()) currentPos-= 5; 
       break; 
      case KeyEvent.VK_RIGHT: if(horizontalyInBounds()) currentPos+= 5; 
       break; 
     } 
     repaint(); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
    } 
} 

は、任意の実行可能なコードが必要とされなければならない場合は、次の

import java.awt.Color; 
    import java.awt.Graphics; 
    import java.util.Random; 

    import javax.swing.JFrame; 
    import javax.swing.JLabel; 


public class test extends JFrame { 

private AreaOfGame areaOfGame; 

public test() 
{ 
    super(""); 
    setVisible(true); 
    this.setBackground(Color.darkGray); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.pack(); 
    setLayout(null); 
    setBounds(200, 10, 400, 700); 

    areaOfGame = new AreaOfGame(); 
    this.add(areaOfGame); 

    startGame(); 
} 

public int generateNext() 
{ 
    Random r = new Random(); 
    int n = r.nextInt(7); 
    return n; 
} 

public void startGame() 
{ 
    while(!areaOfGame.GameOver()) 
    { 
     areaOfGame.startGame(generateNext()); 
    } 
} 


public static void main(String[] args) { 
    new MainFrame(); 
} 


import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

import javax.swing.JPanel; 

public class AreaOfGame extends JPanel { 


    private static final int rightside = 370; 

    private int bottom; 
    private int top; 

    private int currentPos; 
    private int currentver; 
    private KeyLis listener; 

    public AreaOfGame() 
    { 
     super(); 

     bottom = 650; 
     top = 50; 
     setLayout(null); 
     setBounds(20, 50, 350, 600); 
     setVisible(true); 


     this.setBackground(Color.lightGray); 

     listener = new KeyLis(); 
     this.setFocusable(true); 
     if(this.requestFocus(true)) 
      System.out.println("true");; 
     this.addKeyListener(listener); 


     currentPos = 150; 
     currentver=0; 
    } 

    public void startGame(int n) 
    { 
     while(verticallyInBound()){ 
      System.out.println("anything"); 

     } 


    } 

    public boolean verticallyInBound() 
    { 
     if(currentPos<= bottom -50) 
      return true; 
     return false; 
    } 


    public boolean GameOver() 
    { 
     if(top>= bottom){ 
      System.out.println("game over"); 
      return true; 
     } 

     else return false; 
    } 


    public boolean horizontalyInBounds() 
    { 
     if(currentPos<=rightside && currentPos>= 20) 
      return true; 
     else return false; 
    } 


class KeyLis implements KeyListener{ 

     @Override 
     public void keyPressed(KeyEvent e) { 
      System.out.println("called"); 
      currentver += 5; 
      switch (e.getKeyCode()) { 
       case KeyEvent.VK_LEFT : if(horizontalyInBounds()) currentPos-= 5; break; 
       case KeyEvent.VK_RIGHT: if(horizontalyInBounds()) currentPos+= 5; break; 
      } 
      repaint(); 


     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void keyTyped(KeyEvent e) { 
      System.out.println("called 3"); 
     } 
} 

} 
+1

あなたは多分問題のあっ、私達にあなたの「KeyLis」クラスを与えることができればそれが役立つだろう。 – eboix

+0

ありがとう、私はリスナークラスを追加 – BBB

+0

うーん...私は一度に同様の問題があったと思う。メソッド "e.consume()"をkeyPressed(KeyEvent e)メソッドの最後まで呼び出してみてください。それが動作するかどうか私に教えてください。 – eboix

答えて

12

私はJPanelのが持っていたか、トップレベルのウィンドウの前に(レンダリングされた前にフォーカスを要求していることを賭けるpack()またはsetVisible(true)もしそうなら、これはうまくいきません。フォーカスリクエストは、コンポーネントがレンダリングされた後にのみ、に許可されます。 requestFocus()へのあなたの電話が返ってきたことを確認しましたか?あなたの呼び出しが成功のチャンスを得るためには、それは真実を返さなければなりません。またrequestFocus()ではなくrequestFocusInWindow()を使用する方が良いでしょう。

さらに重要なのは、KeyListenersをこの代わりに使用するべきではなく、キー入力に対応するためにSwing自身が使用するより高いレベルの概念です。

編集
SSCCEの例:

import java.awt.Dimension; 
import java.awt.event.*; 
import javax.swing.*; 

public class TestKeyListener extends JPanel { 
    private KeyLis listener; 

    public TestKeyListener() { 
     add(new JButton("Foo")); // something to draw off focus 
     listener = new KeyLis(); 
     this.setFocusable(true); 
     this.requestFocus(); 
     this.addKeyListener(listener); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(300, 200); 
    } 

    private class KeyLis extends KeyAdapter { 
     @Override 
     public void keyPressed(KeyEvent e) { 
     switch (e.getKeyCode()) { 
     case KeyEvent.VK_LEFT: 
      System.out.println("VK_LEFT pressed"); 
      break; 
     case KeyEvent.VK_RIGHT: 
      System.out.println("VK_RIGHT pressed"); 
      break; 
     } 
     } 
    } 

    private static void createAndShowGui() { 
     TestKeyListener mainPanel = new TestKeyListener(); 

     JFrame frame = new JFrame("TestKeyListener"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

編集2
とキーバインディングを使用して同等のSSCCE

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class TestKeyBindings extends JPanel { 

    public TestKeyBindings() { 
     add(new JButton("Foo")); // something to draw off focus 
     setKeyBindings(); 
    } 

    private void setKeyBindings() { 
     ActionMap actionMap = getActionMap(); 
     int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 
     InputMap inputMap = getInputMap(condition); 

     String vkLeft = "VK_LEFT"; 
     String vkRight = "VK_RIGHT"; 
     inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), vkLeft); 
     inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), vkRight); 

     actionMap.put(vkLeft, new KeyAction(vkLeft)); 
     actionMap.put(vkRight, new KeyAction(vkRight)); 

    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(300, 200); 
    } 

    private class KeyAction extends AbstractAction { 
     public KeyAction(String actionCommand) { 
     putValue(ACTION_COMMAND_KEY, actionCommand); 
     } 

     @Override 
     public void actionPerformed(ActionEvent actionEvt) { 
     System.out.println(actionEvt.getActionCommand() + " pressed"); 
     } 
    } 

    private static void createAndShowGui() { 
     TestKeyBindings mainPanel = new TestKeyBindings(); 

     JFrame frame = new JFrame("TestKeyListener"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

編集3
最近のSSCCEに関しては、while (true)ループがSwingイベントスレッドをブロックしているため、ユーザーの操作やペイントが行われない可能性があります。 while (true)ではなく、スイングタイマーを使用する方がよいでしょう。例:

import java.awt.*; 
import java.awt.event.*; 
import java.util.Random; 

import javax.swing.*; 

public class BbbTest extends JFrame { 

    private AreaOfGame areaOfGame; 

    public BbbTest() { 
     super(""); 
//  setVisible(true); 
     this.setBackground(Color.darkGray); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.pack(); 
     setLayout(null); 
     setBounds(200, 10, 400, 700); 

     areaOfGame = new AreaOfGame(); 
     this.add(areaOfGame); 
     setVisible(true); 

     startGame(); 
    } 

    public int generateNext() { 
     Random r = new Random(); 
     int n = r.nextInt(7); 
     return n; 
    } 

    public void startGame() { 
     // while (!areaOfGame.GameOver()) { 
     // areaOfGame.startGame(generateNext()); 
     // } 

     areaOfGame.startGame(generateNext()); 
    } 

    public static void main(String[] args) { 
     new BbbTest(); 
    } 

    class AreaOfGame extends JPanel { 

     private static final int rightside = 370; 

     private int bottom; 
     private int top; 

     private int currentPos; 
     private int currentver; 
     private KeyLis listener; 

     public AreaOfGame() { 
     super(); 

     bottom = 650; 
     top = 50; 
     setLayout(null); 
     setBounds(20, 50, 350, 600); 
     setVisible(true); 

     this.setBackground(Color.lightGray); 

     listener = new KeyLis(); 
     this.setFocusable(true); 
     if (this.requestFocus(true)) 
      System.out.println("true"); 
     ; 
     this.addKeyListener(listener); 

     currentPos = 150; 
     currentver = 0; 
     } 

     public void startGame(int n) { 
     // while (verticallyInBound()) { 
     // System.out.println("anything"); 
     // } 

     int timeDelay = 50; // msecs delay 
     new Timer(timeDelay , new ActionListener() { 

      public void actionPerformed(ActionEvent arg0) { 
       System.out.println("anything"); 
      } 
     }).start(); 

     } 

     public boolean verticallyInBound() { 
     if (currentPos <= bottom - 50) 
      return true; 
     return false; 
     } 

     public boolean GameOver() { 
     if (top >= bottom) { 
      System.out.println("game over"); 
      return true; 
     } 

     else 
      return false; 
     } 

     public boolean horizontalyInBounds() { 
     if (currentPos <= rightside && currentPos >= 20) 
      return true; 
     else 
      return false; 
     } 

     class KeyLis implements KeyListener { 

     @Override 
     public void keyPressed(KeyEvent e) { 
      System.out.println("called"); 
      currentver += 5; 
      switch (e.getKeyCode()) { 
      case KeyEvent.VK_LEFT: 
       if (horizontalyInBounds()) 
        currentPos -= 5; 
       break; 
      case KeyEvent.VK_RIGHT: 
       if (horizontalyInBounds()) 
        currentPos += 5; 
       break; 
      } 
      repaint(); 

     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void keyTyped(KeyEvent e) { 
      System.out.println("called 3"); 
     } 
     } 
    } 
} 
+0

実際にはこれらはすべて、フレームにpack()とsetVisible(true)が設定された後に実行されます。キーバインディングを使用すると唯一の選択肢ですが、体が見えないため、なぜ動作しないのか本当に知りたいですこの問題が発生する前に、フォーカスのためにnullポインタをチェックしました。メソッドが呼び出されているため、リスナーが追加されましたが、処理されませんでした。 – BBB

+0

@BBB:もう一度、 'requestFocus()'メソッドの呼び出しが返ってきたことを確認しましたか?それは真実か偽りか? –

+0

これは常にfalseを返しています – BBB

0

「TAB」ボタンを使用してボタンとキーリスナーを切り替えることができます。 私はそれを押すと、キーリスナーが機能しない1つのボタンを持つプログラムを持っています。 "TAB"ボタンを押すと、プログラムの "注意"または "フォーカス"がキーリスナーに戻ります。

多分これは役立ちます:http://docstore.mik.ua/orelly/java-ent/jfc/ch03_08.htm

関連する問題