慢慢地将圆圈移动到某个地方

时间:2013-12-08 16:28:41

标签: java swt

我试图让一个圆圈缓慢移动到某个地方,但它不起作用 圆圈移动到某个地方immediatley没有画布的重绘之间的延迟,我不明白为什么。 (在mouseUPListener中,圆圈应该缓慢移动到原来的位置)

这是我的代码: 第一类:

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class MouseListenerUsing {   
    static int i =0, R1=75,inCircleX=100,inCircleY=100,oldX,oldY;
    static int outCircleX=inCircleX , outCircleY=inCircleY, R2=200,distX,distY,IT_NUM=100;
    static Canvas c;
    static Display display;
    static boolean  flagY=false,flagX=false;
    static SecondClass se;
    public static void main(String[] args) {
    display = new Display();
    Shell shell = new Shell(display);
    shell.setSize(430, 460);
    c=new Canvas(shell,SWT.BORDER);
    c.setSize(370,380);
    c.setLocation(21, 21);

    c.addPaintListener(new PaintListener(){
        public void paintControl(PaintEvent e) { 
            e.gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
            e.gc.drawOval(outCircleX-((R2-R1)/2), outCircleY-((R2-R1)/2), R2, R2);
            e.gc.fillOval(inCircleX, inCircleY, R1, R1);
        }       
    });    
    c.addMouseMoveListener(new MouseMoveListener(){
        @Override
        public void mouseMove(MouseEvent e){
            if (i==2)   
            {
                if (Math.sqrt(Math.pow((inCircleX+(R1/2))-((outCircleX-((R2-R1)/2)+(R2/2))),2)+Math.pow((inCircleY+(R1/2))-((outCircleY-((R2-R1)/2))+(R2/2)),2))<=R2/2)
                {   // distance between the two centers                                 
                    inCircleX = e.x+oldX;
                    inCircleY = e.y+oldY;
                    c.redraw();
                }
            }
        }       
    });
    c.addMouseListener(new MouseListener() {
        public void mouseDoubleClick(MouseEvent e) {}
        public void mouseDown(MouseEvent e) 
        {        
            if (Math.sqrt(Math.pow(e.x-inCircleX-R1/2,2)+Math.pow(e.y-inCircleY-R1/2,2))<=R1/2)
            {
                oldX=inCircleX-e.x;
                oldY=inCircleY-e.y;
                i=2;
            }
        }
        public void mouseUp(MouseEvent e)
        {   
            if ((inCircleX+(R1/2))>(outCircleX-((R2-R1)/2)+(R2/2))) flagX=true;
            else if ((inCircleX+(R1/2))<(outCircleX-((R2-R1)/2)+(R2/2))) flagX=false;
            if ((inCircleY+(R1/2))>(outCircleY-((R2-R1)/2)+(R2/2))) flagY=true;
            else if ((inCircleY+(R1/2))<(outCircleY-((R2-R1)/2)+(R2/2))) flagY=false;
            distX = ((inCircleX+(R1/2))-((outCircleX-((R2-R1)/2)+(R2/2))))/IT_NUM;
            distX = ((inCircleY+(R1/2))-((outCircleY-((R2-R1)/2)+(R2/2))))/IT_NUM;
            se = new SecondClass();
            display.timerExec(1000, se);            

            inCircleX = outCircleX;
            inCircleY = outCircleY;
            c.redraw();
            i=1;
        }
    });
    shell.open();
    while(!shell.isDisposed())
        if (!display.readAndDispatch())
            display.sleep();    
    display.dispose();
  }
 }

第二类:

public class SecondClass implements Runnable{
    static int i =MouseListenerUsing.IT_NUM;
    @Override
    public void run() {
        Surfing();

    }
    public void Surfing()
    {
        if (i>0){
            if (MouseListenerUsing.flagX==true) MouseListenerUsing.inCircleX = MouseListenerUsing.inCircleX - MouseListenerUsing.distX;
            if (MouseListenerUsing.flagX==false) MouseListenerUsing.inCircleX = MouseListenerUsing.inCircleX + MouseListenerUsing.distX;
            if (MouseListenerUsing.flagY==true) MouseListenerUsing.inCircleY = MouseListenerUsing.inCircleY - MouseListenerUsing.distY;
            if (MouseListenerUsing.flagY==false) MouseListenerUsing.inCircleY = MouseListenerUsing.inCircleY + MouseListenerUsing.distY;
            MouseListenerUsing.c.redraw();
            i--;
        }
        if (i==0)
        {
            MouseListenerUsing.display.timerExec(-1, MouseListenerUsing.se);
        }
    }




}

有人可以解释我的问题并提出解决方案吗? 谢谢

新代码:

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class MouseListenerUsing {   
    static int i =0, R1=75,inCircleX=100,inCircleY=100,oldX,oldY,count=0;
    static int outCircleX=inCircleX , outCircleY=inCircleY, R2=200,distX,distY,IT_NUM=20;
    static boolean  flagY=false,flagX=false;

    public static void main(String[] args) {
    final Display display = new Display();
    Shell shell = new Shell(display);
    shell.setSize(430, 460);
    final Canvas c=new Canvas(shell,SWT.BORDER);
    c.setSize(370,380);
    c.setLocation(21, 21);

    c.addPaintListener(new PaintListener(){
        public void paintControl(PaintEvent e) { 
            e.gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
            e.gc.drawOval(outCircleX-((R2-R1)/2), outCircleY-((R2-R1)/2), R2, R2);
            e.gc.fillOval(inCircleX, inCircleY, R1, R1);    
        }       
    });    
    c.addMouseMoveListener(new MouseMoveListener(){
        @Override
        public void mouseMove(MouseEvent e){
            if (i==2)   
            {
                if (Math.sqrt(Math.pow((inCircleX+(R1/2))-((outCircleX-((R2-R1)/2)+(R2/2))),2)+Math.pow((inCircleY+(R1/2))-((outCircleY-((R2-R1)/2))+(R2/2)),2))<=R2/2)
                {   // distance between the two centers                                 
                    inCircleX = e.x+oldX;
                    inCircleY = e.y+oldY;
                    c.redraw();
                }
            }
        }       
    });
    c.addMouseListener(new MouseListener() {
        public void mouseDoubleClick(MouseEvent e) {}
        public void mouseDown(MouseEvent e) 
        {        
            if (Math.sqrt(Math.pow(e.x-inCircleX-R1/2,2)+Math.pow(e.y-inCircleY-R1/2,2))<=R1/2)
            {
                oldX=inCircleX-e.x;
                oldY=inCircleY-e.y;
                i=2;
            }
        }
        public void mouseUp(MouseEvent e)
        {        
            i=1;            
            if ((inCircleX+(R1/2))>(outCircleX-((R2-R1)/2)+(R2/2))) flagX=true;
            else if ((inCircleX+(R1/2))<(outCircleX-((R2-R1)/2)+(R2/2))) flagX=false;
            if ((inCircleY+(R1/2))>(outCircleY-((R2-R1)/2)+(R2/2))) flagY=true;
            else if ((inCircleY+(R1/2))<(outCircleY-((R2-R1)/2)+(R2/2))) flagY=false;
            //it = (Math.sqrt(Math.pow((inCircleX+(R1/2))-((outCircleX-((R2-R1)/2)+(R2/2))),2)+Math.pow((inCircleY+(R1/2))-((outCircleY-((R2-R1)/2))+(R2/2)),2))); //distance between centers
            distX = ((inCircleX+(R1/2))-((outCircleX-((R2-R1)/2)+(R2/2))))/IT_NUM;
            distY = ((inCircleY+(R1/2))-((outCircleY-((R2-R1)/2)+(R2/2))))/IT_NUM;
            final Runnable drawThread = new Runnable()
            {
                @Override
                public void run() {     

                    if (flagX==true)  inCircleX = inCircleX - distX;
                    if (flagX==false) inCircleX = inCircleX + distX;
                    if (flagY==true)  inCircleY = inCircleY - distY;
                    if (flagY==false) inCircleY = inCircleY + distY;
                    c.redraw();
                    IT_NUM--;
                    System.out.println(IT_NUM);
                    if (IT_NUM==17) 
                    {                           
                        display.timerExec(-1, this);

                    }
                    display.timerExec(10, this);            
                }   

            };
            display.timerExec(10, drawThread);
            //display.timerExec(-1, drawThread);
            System.out.println("hello");
            //inCircleX = outCircleX;
            //inCircleY = outCircleY;
            c.redraw();
        }
    });
    shell.open();
    while(!shell.isDisposed())
        if (!display.readAndDispatch())
            display.sleep();    
    display.dispose();
  }
 }

2 个答案:

答案 0 :(得分:0)

这是一个简单的例子。它将从左上角移动到右下角:

private static int          x               = 0;
private static int          y               = 0;
private static int          r               = 5;

// The timer interval in milliseconds
private static final int    TIMER_INTERVAL  = 10;

public static void main(String[] args)
{
    final Display display = new Display();
    Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());

    final Canvas canvas = new Canvas(shell, SWT.NONE);

    canvas.addListener(SWT.Paint, new Listener()
    {
        @Override
        public void handleEvent(Event e)
        {
            e.gc.drawOval(x++, y++, r, r);
        }
    });

    final Runnable drawThread = new Runnable()
    {
        @Override
        public void run()
        {
            canvas.redraw();

            if(x < 400 && y < 400)
                display.timerExec(TIMER_INTERVAL, this);
        }
    };

    display.timerExec(TIMER_INTERVAL, drawThread);

    shell.pack();
    shell.setSize(400, 400);
    shell.open();
    while (!shell.isDisposed())
        if (!display.readAndDispatch())
            display.sleep();

    // Kill the timer
    display.timerExec(-1, drawThread);
    display.dispose();
}

答案 1 :(得分:0)

您可以开始使用计时框架来更好地控制动画。我用了

https://kenai.com/projects/trident/pages/Home

https://java.net/projects/timingframework

两者都很不错。 Trident支持SWT(在内部使用,它使用Display.timerExec())