3

マインスイーパを実装していますが、マウス イベントの処理に少し問題があります。(mousePressed ではなく) mouseRelease でアクションを実行したいので、ユーザーはマウス ボタンを押した後に気が変わることができます。次の 3 つのアクションがあります。

  1. LMB リリース - 現在のフィールドを表示
  2. RMB がリリースされました - 現在のフィールドにフラグを立てます
  3. LMB と RMB の両方がリリースされました - 隣接するフィールドをハイライトまたは表示します

アクションはそれほど重要ではありません。私が問題を抱えているのは、それらをトリガーする方法です。

ケース 1 と 2 では、他のボタンが押されていません。これは簡単に確認できます。

問題は、両方のボタンを離すと、mouseRelease メソッドが 2 回呼び出されることです。両方のボタンを離すまでの遅延が大きすぎる場合は、アクションをトリガーしないことをお勧めします。つまり、両方のボタンがほぼ同時に離された場合にのみトリガーする必要があります。

たとえば、ボタン 1 を放したときにボタン 3 が押されていることは簡単に確認できますが、あまり役に立ちません。

現時点では、最初のボタンが離された時間を保存し、それを別のボタンが離された時間と比較する以外に考えがありません。差が十分に小さい場合は、アクションをトリガーします。

System.currentTimeMillis() または System.nanoTime() で遊ぶという考えはあまり好きではありません。それを行うより良い方法があるかどうか疑問に思いますか?

解決:

問題を非常に単純化したのは、ユーザーがマウス ポインタを別のフィールドにドラッグできないようにすることでした (そのため、「選択された」フィールドが変更されました)。両方のボタンを放す間の遅延は問題ではありません。マウス ポインタが別のフィールドに移動すると、すべてがクリアされます。コード スニペットは次のとおりです。

private static final int B1DM = MouseEvent.BUTTON1_DOWN_MASK;
private static final int B3DM = MouseEvent.BUTTON3_DOWN_MASK;

private boolean bothWereDown = false;

@Override
public void mousePressed(MouseEvent e) {

    // action if single button pressed
    // in my case this is a sub-action of pressing both buttons

    int both = B1DM | B3DM;
    bothWereDown = (e.getModifiersEx() & both) == both;

    if (bothWereDown) {
        // action if both buttons pressed
    }
}

@Override
public void mouseDragged(MouseEvent e) {

    // some other code

    if ( /* if pointer leaves field where mouse was pressed */) {
        // some other code
        bothWereDown = false;
        // some other code
    }
}

@Override
public void mouseReleased(MouseEvent e) {
    // some other code

    if (e.getButton() == MouseEvent.BUTTON1) {
        if (bothWereDown) {
            if ((e.getModifiersEx() & B3DM) != B3DM) {
                // action if both released
            }
        } else {
            // action if left button released
        }
    } else if (e.getButton() == MouseEvent.BUTTON3) {
        if (bothWereDown) {
            if ((e.getModifiersEx() & B1DM) != B1DM) {
                // action if both released
            }
        } else {
            // action if right button released
        }
    }

}
4

1 に答える 1

4

明らかな解決策は、マウスの押下も追跡することです。この場合、タイムアウトをいじる必要はないと思います。

したがって、両方のボタンを押してから 1 つを離しても、1 つのボタンを離したとは見なされません。実際、あなたの場合、おそらく何もしないでしょう。他のマウス ボタンも離された場合にのみ、両方のボタンを離したと見なされます。

編集:実際には、マウスの押下を追跡する必要さえありませんが、おそらくボタンが押されたことを視覚的に示したいと考えており、ボタンを離すと効果があります。ただし、ボタンが離され、他のボタンがまだ押されていることを検出した場合は、2 つのボタンのリリースの半分が発生したというフラグを設定するだけで、1 つのボタンを 1 つリリースすると完了します。シングル ボタン リリースでフラグが設定されていない場合、それは 2 ボタン アクションの一部ではなく、代わりにシングル ボタン リリース アクションを実行します。

于 2013-03-09T14:42:45.480 に答える