使组件对 Swing 中的拖动不那么敏感
Posted
技术标签:
【中文标题】使组件对 Swing 中的拖动不那么敏感【英文标题】:Making a component less sensitive to Dragging in Swing 【发布时间】:2010-10-06 01:17:32 【问题描述】:我的一个JComponent
过于激烈地触发了一个mouseDragged
事件。当用户试图点击时,即使鼠标只移动了 1 个像素,它也会将其解释为拖动。
如何为特定组件添加一条规则,相当于:
不要将其视为拖动事件,除非 鼠标移动了 10 个像素 被按下的点。
注意:我知道这不是我操作系统中的系统设置,因为只有该组件上的事件才会受到这种过度敏感的影响。
谢谢。
【问题讨论】:
【参考方案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);
【讨论】:
以上是关于使组件对 Swing 中的拖动不那么敏感的主要内容,如果未能解决你的问题,请参考以下文章