Создание компонента, менее чувствительного к перетаскиванию в Swing - PullRequest
5 голосов
/ 07 февраля 2009

Мой JComponent слишком энергично запускает событие mouseDragged. Когда пользователь пытается щелкнуть, это интерпретируется как перетаскивание, даже если мышь переместилась только на 1 пиксель.

Как бы добавить правило для определенного компонента, которое составило бы:

Не считайте это событием перетаскивания, если только мышь переместилась на 10 пикселей от точка, в которой был нажат.

Примечание: я знаю, что это не системная настройка в моей ОС, поскольку только события в этом компоненте страдают от этой сверхчувствительности.

Спасибо.

Ответы [ 4 ]

4 голосов
/ 25 сентября 2013

Предыдущие ответы объединены, с правильным типом события:

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);
    }
}
3 голосов
/ 08 февраля 2009

Я должен был сделать именно это раньше. Вот мой код обработки событий мыши, урезанный до тех битов, которые связаны с тем, что для перетаскивания требуется несколько пикселей, прежде чем он будет рассматриваться как перетаскивание.

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, генерирующими события щелчка после перетаскивания, которые я должен был обнаружить и подавить.

1 голос
/ 07 февраля 2009

Если я правильно прочитал ваш вопрос, вы отслеживаете как клики, так и события mousedrag. Можете ли вы отследить координаты после mousedown, а затем выполнить короткое вычисление в mousedrag, чтобы увидеть, сдвинула ли мышка желаемое минимальное количество пикселей? Конечно, вы также хотите отменить / сбросить при наведении мыши или когда мышь перетаскивается за пределы вашего JComponent.

Предостережение: я сам этого не делал, но думаю, что именно с этого я и начал бы, если бы это был я.

0 голосов
/ 24 мая 2011

В программном коде Обезьяны, похоже, отсутствует некоторый код, поэтому я написал следующее решение:

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

        if(treePath != null) {
            processChoice();
        }
    }
});

Это по-прежнему будет вызывать событие mouseClicked (), когда пользователь создает не более 10 пикселей «перемещения при перемещении».

Код для прослушивателя кликов:

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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...