0

を現在テスト中KeyEventDispatcherです。

したがって、私は自分自身の メソッドをJFrame実装するものを少し書きました。KeyEventDispatcherkeyPressedkeyReleased

これらのメソッドでは、フラグベースのシステムを使用して、すべての矢印キーの最初のキー押下のみを検出しています。

キーを個別にクリックすると、すべてが機能します。ただし、Right、Up、Left のいずれかを離さずにクリックすると、Left キーは認識されません。

コンソール出力:

右クリック
4
上クリック
6

期待される出力:

右クリック
4
上クリック
6
左クリック
7

私のコードは次のとおりです。

メインクラス:

public class Main {

    public static void main(String[] args) {
        UI m = new UI();
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(m);

    }
}

UI クラス:

public class UI extends JFrame implements KeyEventDispatcher{

    short lurd = 0;

    enum KEYSTATES{
        LEFT(1),
        UP(2),
        RIGHT(4),
        DOWN(8);

        private int m_val;
        KEYSTATES(int val){
            m_val = val;
        }

        public int getm_val(){
            return m_val;
        }

    }

    public UI(){

        setSize(800,600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setVisible(true);

    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {


        switch(e.getID())
        {
        case KeyEvent.KEY_PRESSED:
            keyPressed(e);
            return true;

        case KeyEvent.KEY_RELEASED:
            keyReleased(e);
            return true;

        }
        return false;
    }

    private void keyPressed(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_LEFT && ((lurd & KEYSTATES.LEFT.getm_val()) != KEYSTATES.LEFT.getm_val())){
            lurd |= KEYSTATES.LEFT.getm_val();
            System.out.println("Left clicked");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_UP && ((lurd & KEYSTATES.UP.getm_val()) != KEYSTATES.UP.getm_val()))
        {
            lurd |= KEYSTATES.UP.getm_val();
            System.out.println("Up clicked");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_RIGHT && ((lurd & KEYSTATES.RIGHT.getm_val()) != KEYSTATES.RIGHT.getm_val()))
        {
            lurd |= KEYSTATES.RIGHT.getm_val();
            System.out.println("Right clicked");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_DOWN && ((lurd & KEYSTATES.DOWN.getm_val()) != KEYSTATES.DOWN.getm_val()))
        {
            lurd |= KEYSTATES.DOWN.getm_val();
            System.out.println("Down clicked");
            System.out.println(lurd);
        }


    }

    private void keyReleased(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_LEFT && ((lurd & KEYSTATES.LEFT.getm_val()) == KEYSTATES.LEFT.getm_val())){
            lurd &= ~KEYSTATES.LEFT.getm_val();
            System.out.println("Left released");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_UP && ((lurd & KEYSTATES.UP.getm_val()) == KEYSTATES.UP.getm_val()))
        {
            lurd &= ~KEYSTATES.UP.getm_val();
            System.out.println("Up released");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_RIGHT && ((lurd & KEYSTATES.RIGHT.getm_val()) == KEYSTATES.RIGHT.getm_val()))
        {
            int x = ~KEYSTATES.RIGHT.getm_val();
            lurd &= x;
            System.out.println("Right released");
            System.out.println(lurd);
        }
        else if(e.getKeyCode() == KeyEvent.VK_DOWN && ((lurd & KEYSTATES.DOWN.getm_val()) == KEYSTATES.DOWN.getm_val()))
        {
            lurd &= ~KEYSTATES.DOWN.getm_val();
            System.out.println("Down released");
            System.out.println(lurd);
        }


    }


}
4

1 に答える 1

0

この問題を解決するには、変数が の場合は特定の変数の参照を保持しboolean、を作成し、それぞれがの場合はそれらの変数を作成します。keyspressedtruefalsekeyreleased

次に例を示します。

keyPressed()メソッドは次のとおりです。

public void keyPressed(KeyEvent e)
{
  switch(e.getKeyCode())
  {
    case VK_LEFT: setLeftKeyPressed(true);
                  break;
    case VK_RIGHT: setRightKeyPressed(true);
                   break;
    case VK_UP: setUpKeyPressed(true);
                break;
    case VK_DOWN: setDownKeyPressed(true);
                  break;
    //...
  }
  printKeyStates();
}

そして、ここにkeyReleased()方法があります:

public void keyReleased(KeyEvent e)
{
  switch(e.getKeyCode())
  {
    case VK_LEFT: setLeftKeyPressed(false);
                  break;
    case VK_RIGHT: setRightKeyPressed(false);
                   break;
    case VK_UP: setUpKeyPressed(false);
                break;
    case VK_DOWN: setDownKeyPressed(false);
                  break;
    //...
  }
  printKeyStates();
}

printKeyStates()メソッドは次のようになります。

public void printKeyStates()
{
  print("Left", isLeftKeyPressed());
  print("Right", isRightKeyPressed());
  print("Up", isUpKeyPressed());
  print("Down", isDownKeyPressed());
}

private void print(String key, boolean isPressed)
{
  System.out.println(key + " key is " + (isPressed ? "" : "NOT ") + "pressed.");
}

変数は次のbooleanようになります。

private boolean isLeftKeyPressed;
private boolean isRightKeyPressed;
private boolean isUpKeyPressed;
private boolean isDownKeyPressed;

そして彼らのsettersような:

public void setLeftKeyPressed(boolean value)
{
  isLeftKeyPressed = value;
}

残りのセッターも同様に...

などgetters

public boolean isLeftKeyPressed()
{
  return isLeftKeyPressed;
}

同様に、残りのゲッターも...

通常、ゲームや、このような動作が予想されるネットワーク リモート コントロールでは、この手法によって解決されます。

変数の違いにより、flips任意booleanの で発生した「クリック」の数がわかりますkey。その「クリック」数を記録するには、任意のキーに対して発生したクリック数の状態を保持するカウント変数を使用できます。

これを行う方法は次のとおりです。

int leftKeyClickCount = 0; // Initially ZERO

次に、setter変数isLeftKeyPressedで、次のようなことができます。

public void setLeftKeyPressed(boolean value)
{
  if(isLeftKeyPressed != value)
  {
    isLeftKeyPressed = value;
    ++leftKeyClickCount;
  }
}

同様に、他のセッターを書くこともできます...

次に、次のような適切なxyzKeyClickCount変数値を出力することで、各キーのクリック数を出力できます。

System.out.println("Left key clicked: " + leftKeyClickCount + " time(s).");
于 2014-03-12T15:47:52.510 に答える