【问题标题】:Making a component less sensitive to Dragging in Swing使组件对 Swing 中的拖动不那么敏感
【发布时间】:2010-10-06 01:17:32
【问题描述】:

我的一个JComponent 过于激烈地触发了一个mouseDragged 事件。当用户试图点击时,即使鼠标只移动了 1 个像素,它也会将其解释为拖动。

如何为特定组件添加一条规则,相当于:

不要将其视为拖动事件,除非 鼠标移动了 10 个像素 被按下的点。

注意:我知道这不是我操作系统中的系统设置,因为只有该组件上的事件才会受到这种过度敏感的影响。

谢谢。

【问题讨论】:

    标签: java swing drag-and-drop


    【解决方案1】:

    以前的答案结合在一起,并带有适当的事件类型:

    public class DragInsensitiveMouseClickListener implements MouseInputListener {
    
        protected static final int MAX_CLICK_DISTANCE = 15;
    
        private final MouseInputListener target;
    
        public MouseEvent pressed;
    
        public DragInsensitiveMouseClickListener(MouseInputListener target) {
            this.target = target;
        }
    
        @Override
        public final void mousePressed(MouseEvent e) {
            pressed = e;
            target.mousePressed(e);
        }
    
        private int getDragDistance(MouseEvent e) {
            int distance = 0;
            distance += Math.abs(pressed.getXOnScreen() - e.getXOnScreen());
            distance += Math.abs(pressed.getYOnScreen() - e.getYOnScreen());
            return distance;
        }
    
        @Override
        public final void mouseReleased(MouseEvent e) {
            target.mouseReleased(e);
    
            if (pressed != null) {
                if (getDragDistance(e) < MAX_CLICK_DISTANCE) {
                    MouseEvent clickEvent = new MouseEvent((Component) pressed.getSource(),
                            MouseEvent.MOUSE_CLICKED, e.getWhen(), pressed.getModifiers(),
                            pressed.getX(), pressed.getY(), pressed.getXOnScreen(), pressed.getYOnScreen(),
                            pressed.getClickCount(), pressed.isPopupTrigger(), pressed.getButton());
                    target.mouseClicked(clickEvent);
                }
                pressed = null;
            }
        }
    
        @Override
        public void mouseClicked(MouseEvent e) {
            //do nothing, handled by pressed/released handlers
        }
    
        @Override
        public void mouseEntered(MouseEvent e) {
            target.mouseEntered(e);
        }
    
        @Override
        public void mouseExited(MouseEvent e) {
            target.mouseExited(e);
        }
    
        @Override
        public void mouseDragged(MouseEvent e) {
            if (pressed != null) {
                if (getDragDistance(e) < MAX_CLICK_DISTANCE) return; //do not trigger drag yet (distance is in "click" perimeter
                pressed = null;
            }
            target.mouseDragged(e);
        }
    
        @Override
        public void mouseMoved(MouseEvent e) {
            target.mouseMoved(e);
        }
    }
    

    【讨论】:

      【解决方案2】:

      我以前必须这样做。这是我的鼠标事件处理代码,减少到仅与使拖动相关的位在被视为拖动之前需要几个像素。

      public void mousePressed(int mod, Point loc) {
          pressLocation=copyLocation(loc,pressLocation);
          dragLocation=null;
          }
      
      public void mouseReleased(int mod, Point loc) {
          if(pressLocation!=null && dragLocation!=null) {
              // Mouse drag reverted to mouse click - not dragged far enough
              // action for click
              pressLocation=null;
              }
          else if(dragLocation!=null) {
              // action for drag completed
              }
          else {
              // do nothing
              }
      
          pressLocation=null;
          dragLocation=null;
          }
      
      public void mouseDragged(int mod, Point loc) {
          if(pressLocation!=null) {                                                   // initial drag actions following mouse press
              dragLocation=pressLocation;                                             // consider dragging to be from start point
              if(Math.abs(loc.x-pressLocation.x)<dragMinimum && Math.abs(loc.y-pressLocation.y)<dragMinimum) {
                  return;                                                             // not dragged far enough to count as drag (yet)
                  }
              // action drag from press location
              pressLocation=null;
              }
          else {
              // action drag from last drag location
              dragLocation=copyLocation(loc,dragLocation);
              }
          }
      

      请注意,我还遇到了 Java 一些 JVM 在拖动后生成点击事件的问题,我必须检测并抑制它。

      【讨论】:

        【解决方案3】:

        如果我正确阅读了您的问题,那么您正在跟踪单击和鼠标拖动事件。您可以在 mousedown 时跟踪坐标,然后在 mousedrag 中进行简短计算以查看鼠标是否已移动所需的最小像素数?当然,您还想在 mouseup 或鼠标被拖动到 JComponent 边界之外时取消/重置。

        警告:我自己没有这样做,但我认为如果是我,我会从这里开始。

        【讨论】:

          【解决方案4】:

          Software Monkey 的代码好像少了一些代码,所以我写了这个解决方案:

          navigationTree.addMouseListener(new DragInsensitiveMouseClickListener(10) {
              @Override
              public void mouseClicked(MouseEvent e) {
                  TreePath treePath = navigationTree.getPathForLocation(e.getX(), e.getY());
          
                  if(treePath != null) {
                      processChoice();
                  }
              }
          });
          

          当用户产生最多 10 个像素的“拖动行程”时,这仍会触发 mouseClicked() 事件。

          点击监听的代码:

          import java.awt.Point;
          import java.awt.event.MouseAdapter;
          import java.awt.event.MouseEvent;
          
          public class DragInsensitiveMouseClickListener extends MouseAdapter {
          
              private final int allowedTravel;
          
              public Point mouseDownPoint;
          
              public DragInsensitiveMouseClickListener(int allowedTravel) {
                  this.allowedTravel = allowedTravel;
              }
          
              @Override
              public void mousePressed(MouseEvent e) {
                  mouseDownPoint = e.getPoint();
              }
          
              @Override
              public void mouseReleased(MouseEvent e) {
                  double horizontalTravel = Math.abs(mouseDownPoint.getX() - e.getX());
                  double verticalTravel = Math.abs(mouseDownPoint.getY() - e.getY());
          
                  if (horizontalTravel < allowedTravel && verticalTravel < allowedTravel) {
                      mouseClicked(e);
                  }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-07
            • 2016-12-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多