2017-01-14 25 views
0

私はJavaFXで次のことをしようとしています。私は、画面上のものを描画するキャンバスを使用していると私は次のことが起こるしたい:JavaFXの区別ドラッグアンドクリック

私は(速いプレスとリリースのような)キャンバス面をクリックすると:私はキャンバスの表面にドラッグすると、何かが

起こります(押すと移動してから離してください):何かELSEが発生します

ドラッグするとクリックアクションを除外したいので、ドラッグするとどうなりますか?残念ながら、マウスを放すと、ドラッグしてもリリースイベントとクリックイベントの両方が起動するようです。

答えて

1

少し遅れますが、誰かが解決のためにここに来る場合に備えて。私はそれを処理するための簡単なクラスを作成しました。

使用法:

clickNotDragDetectingOn(yourNode) 
     .withPressedDurationTreshold(150) 
     .setOnMouseClickedNotDragged((mouseEvent) -> { 
      // logic here 
     }); 

コード:

class MouseClickNotDragDetector { 

    private final Node node; 

    private Consumer<MouseEvent> onClickedNotDragged; 
    private boolean wasDragged; 
    private long timePressed; 
    private long timeReleased; 
    private long pressedDurationTreshold; 

    private MouseClickNotDragDetector(Node node) { 
     this.node = node; 

     node.addEventHandler(MOUSE_PRESSED, (mouseEvent) -> { 
      this.timePressed = currentTimeMillis(); 
     }); 

     node.addEventHandler(MOUSE_DRAGGED, (mouseEvent) -> { 
      this.wasDragged = true; 
     }); 

     node.addEventHandler(MOUSE_RELEASED, (mouseEvent) -> { 
      this.timeReleased = currentTimeMillis(); 
      this.fireEventIfWasClickedNotDragged(mouseEvent); 
      this.clear(); 
     }); 

     this.pressedDurationTreshold = 200; 
    } 

    static MouseClickNotDragDetector clickNotDragDetectingOn(Node node) { 
     return new MouseClickNotDragDetector(node); 
    } 

    MouseClickNotDragDetector withPressedDurationTreshold(long durationTreshold) { 
     this.pressedDurationTreshold = durationTreshold; 
     return this; 
    } 

    MouseClickNotDragDetector setOnMouseClickedNotDragged(Consumer<MouseEvent> onClickedNotDragged) { 
     this.onClickedNotDragged = onClickedNotDragged; 
     return this; 
    } 

    private void clear() { 
     this.wasDragged = false; 
     this.timePressed = 0; 
     this.timeReleased = 0; 
    } 

    private void fireEventIfWasClickedNotDragged(MouseEvent mouseEvent) { 
     if (this.wasDragged) { 
      debug("[CLICK-NOT-DRAG] dragged!"); 
      return; 
     } 
     if (this.mousePressedDuration() > this.pressedDurationTreshold) { 
      debug("[CLICK-NOT-DRAG] pressed too long, not a click!"); 
      return; 
     } 
     debug("[CLICK-NOT-DRAG] click!"); 
     this.onClickedNotDragged.accept(mouseEvent); 
    } 

    private long mousePressedDuration() { 
     return this.timeReleased - this.timePressed; 
    } 
} 
1

isStillSincePress()は、 APIの両方のgetEventType()と一緒に使用できます。

ユーザビリティを向上させるために、MOUSE_PRESSEDMOUSE_RELEASEDの間のマウス移動のしきい値を実装する必要があります。

0

@ wcomnisky

ありがとうございました。私は最後に何をしましたか(リリースイベントハンドラでisStillSincePress()を使用しようとしましたが、それはクリック音として近距離ドラッグを処理しているようでした)。これはマウスプレスハンドラで記録しました座標を押してください(おそらく、このアイデアはisStillSincePressed()メソッドに似ています。その名前/説明で提案されている可能性があります)pressX = event.getX(); pressY = event.getY()と私はこれを行います:if((pressX == event.getX()) && (pressY == event.getY())) doClickAction(); else doDragEndAction()。ドラッグしている間にアクションを処理するために働くようです。通常のドラッグハンドラを使用してみます。

関連する問題