【问题标题】:JavaFX distinguish Drag and ClickJavaFX 区分 Drag 和 Click
【发布时间】:2017-12-31 20:46:56
【问题描述】:

我正在尝试在 JavaFX 中执行以下操作。我正在使用 Canvas 在屏幕上绘制东西,我希望发生以下情况:

当我点击 Canvas 表面时(例如快速按下和释放):发生了一些事情

当我在 Canvas 表面上拖动时(例如按下并移动,然后松开):其他情况发生

但是如果我拖动,我希望它排除点击操作,所以如果我拖动,如果我点击会发生什么不应该发生。可悲的是,似乎当我释放鼠标时,释放和单击事件都会启动,即使我拖动也是如此。

【问题讨论】:

    标签: java javafx click mouseevent drag


    【解决方案1】:

    isStillSincePress() 方法可以与getEventType() 一起使用,两者都来自MouseEvent API。

    也许您需要为MOUSE_PRESSEDMOUSE_RELEASED 之间的鼠标移动设置一个阈值,以提高可用性。

    【讨论】:

      【解决方案2】:

      有点晚了,但万一有人来这里寻求解决方案。我创建了一个简单的类来处理它。

      用法:

      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;
          }
      }
      

      【讨论】:

        【解决方案3】:

        @wcomnisky

        非常感谢您的帮助。我最后做了什么(我尝试在释放事件处理程序中使用 isStillSincePress() ,它似乎仍然将短距离拖动视为点击......虽然我可能做错了什么)是这样的:在我记录的鼠标按下处理程序中按下坐标(也许这个想法类似于 isStillSincePressed() 方法。它的名称/描述可能已经暗示了)pressX = event.getX(); pressY = event.getY() 并在鼠标释放处理程序中执行此操作:if( (pressX == event.getX() ) &amp;&amp; (pressY == event.getY()) ) doClickAction(); else doDragEndAction()。似乎正在工作.. 在拖动时处理动作,我会尝试使用通常的拖动处理程序。

        【讨论】:

          猜你喜欢
          • 2019-05-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多