什么是最好的UI元素拖动算法

时间:2014-05-20 22:32:48

标签: java algorithm

我制作了一个GUI应用程序,但我坚持使用一种解决方法算法来将ui元素相对于另一个表面(屏幕,画布等)拖动/移动。在我的情况下,我将它用于相对于屏幕的窗口,但这不是重点,因为这个算法应该在任何可能的地方工作。这是我的算法:

代码列表-1

MouseMotionAdapter(){
            int prevX = -1000, prevY = -1000, getX, getY;
            public void mouseDragged(MouseEvent e) {
              //if initial cursor position isn't set 
                if(prevX==-1000){
                    prevX = e.getLocationOnScreen().x;
                    prevY = e.getLocationOnScreen().y;
                    getX = e.getX();
                    getY = e.getY();
                }
               //move element to new position 
                theFrame.setBounds(theFrame.getBounds().x+e.getX()-getX, theFrame.getBounds().y+e.getY()-getY, 880, 583);
                prevX=e.getLocationOnScreen().x;
                prevY=e.getLocationOnScreen().y;
            }

这个算法的问题在于鼠标光标位置肯定是相对于元素固定的,如果我试图移动/拖动元素点击元素的另一个位置/部分,整个元素移动,以便鼠标光标是位于“初始位置”,这不是我想要的行为(我希望它具有我们大多数人所知的行为,例如当我们在桌面上移动图标或在屏幕上移动窗口等时)。

任何人都可以帮忙吗?提前谢谢。

1 个答案:

答案 0 :(得分:2)

在这种情况下,通常的方法是计算当前位置和先前位置之间的差异。然后,这种差异就是“移动”,它被添加到被拖动物体的位置。

(顺便说一句:你似乎根本没有在计算中使用prev...值!)

MouseMotionListener内,大概如下所示:

class MouseDraggingControl implements MouseMotionListener 
{
    private Point previousPoint = new Point();

    @Override 
    public void mouseMoved(MouseEvent e)
    {
        previousPoint = e.getPoint();
    }

    @Override 
    public void mouseDragged(MouseEvent e)
    {
        int movementX = e.getX() - previousPoint.x;
        int movementY = e.getY() - previousPoint.y;

        doMovement(movementX, movementY);

        previousPoint = e.getPoint();
    }
}

在您的情况下,doMovement方法可能会像这样实现:

private void doMovement(int movementX, int movementY)
{
    int oldX = theFrame.getX();
    int oldY = theFrame.getY();
    int newX = oldX + movementX;
    int newY = oldY + movementY;
    theFrame.setLocation(newX, newY);
}

(或类似情况,使用getBounds / setBounds来电)


编辑如果鼠标移动侦听器直接连接到应该拖动的组件,则可能必须使用“屏幕上的位置”:

class MouseDraggingControl implements MouseMotionListener 
{
    private Point previousPoint = new Point();

    @Override 
    public void mouseMoved(MouseEvent e)
    {
        previousPoint = e.getLocationOnScreen();
    }

    @Override 
    public void mouseDragged(MouseEvent e)
    {
        Point p = e.getLocationOnScreen();
        int movementX = p.x - previousPoint.x;
        int movementY = p.y - previousPoint.y;

        doMovement(movementX, movementY);

        previousPoint = e.getLocationOnScreen();
    }
}

如果这不能解决您的问题,我想强调MadProgrammer的评论:一个展示您的实际问题的示例会对此有所帮助。