2013-03-09 1 views
3

지뢰 찾기를 구현 중이며 마우스 이벤트를 처리하는 데 약간의 문제가 있습니다. MouseRelease (mousePressed가 아님)에서 작업을 수행하기를 원하므로 사용자는 마우스 버튼을 누른 후 마음을 바꿀 수 있습니다. - 두 개의 마우스 버튼이 동시에 해제되었는지 감지하는 방법은 무엇입니까?

  • RMB 해제 현재 필드 공개 - 현재 필드에서
  • 모두 LMB을 플래그를 넣어 RMB 해제 - 하이라이트 또는 인접 분야
  • 를 공개 발표

    1. LMB : 세 가지 가능한 행동이있다 액션은 정말로 중요하지 않습니다. 문제는 어떻게 트리거 할 것인가입니다.

      1과 2의 경우에는 다른 버튼이 작동하지 않습니다. 이는 쉽게 확인할 수 있습니다.

      문제는 두 버튼을 모두 놓으면 mouseRelease 메소드가 두 번 호출된다는 것입니다. 두 버튼 릴리스 사이에 너무 큰 지연이있는 경우 조치를 실행하지 않는 것이 좋습니다. 즉, 두 버튼이 거의 동시에 해제 된 경우에만 트리거됩니다.

      예를 들어 버튼 3이 눌려 졌을 때 버튼 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

    명백한 해결책은 마우스 프레스도 추적하는 것입니다. 이 경우 타임 아웃으로 놀 필요가 없다고 생각합니다.

    두 버튼을 모두 누른 다음 하나를 놓으면 하나의 버튼이 해제되지 않습니다. 사실, 귀하의 경우에는 아마 아무 것도하지 않을 것입니다. 다른 마우스 버튼도 놓을 때만 두 버튼을 놓은 것으로 간주합니다.

    편집 : 사실, 마우스 프레스를 추적 할 필요조차 없습니다. 버튼을 눌렀다는 시각적 표시를 원하고 해제하면 효과가 있습니다. 그러나 버튼을 놓았을 때 다른 버튼이 눌려 졌음을 감지하면, 두 개의 버튼 해제 중 절반이 발생했다는 플래그를 설정하면 한 버튼을 한 번 누 르면 완료됩니다. 단일 버튼을 놓을 때 플래그가 설정되어 있지 않으면 두 버튼 동작의 일부가 아니며 대신 단일 버튼 놓기 동작을 수행합니다.

    +0

    실제로이 시간 제한을 무시하는 것이 좋습니다. 이 경우의 행동은 실제로 잘 정의되어 있지 않으며 시스템 지뢰 찾기에서도 이상한 일이 발생합니다. 나는 스윙이 그것을 처리 할 어떤 것도 제공하지 않는다는 것을 알고있다. –

    +0

    @JaroslawPawlak 스윙에서 이것과 관련된 구체적인 것은 모른다.Doubleclick은 내가 생각하기에 스윙에 의해 지원되지만 많은 버튼을 동시에 누르는 "코드"를 구별하면 스스로 처리해야합니다. 하지만 릴리스에서 동작을 트리거하기 때문에 실제로는 더 쉽고 퍼지 타임 아웃 시간을 조정할 필요가 없습니다. – hyde

    +0

    감사합니다. 내 질문을 편집하고 해결책을 추가했습니다. –

    관련 문제