繁体   English   中英

重新绘制Java swing中的组件

[英]Re-painting a component in java swing

我想在单击鼠标后重新绘制一个正方形,但是重新绘制方法将被调用10次。

例如,正方形在x,y中,单击鼠标后将重新绘制:

  • X + 1,Y + 1
  • X + 2,Y + 2
  • X + 3,Y + 3
  • ...
  • ...
  • X + 10,Y + 10

我尝试循环重绘方法10次,但结果是最终绘制而不是整个过程。

public MyPanel() 
{

    setBorder(BorderFactory.createLineBorder(Color.black));

    addMouseListener(new MouseAdapter() 
    {
        public void mousePressed(MouseEvent e) 
        {   
            for(int i=0;i<10;i++)
                moveSquare(redSquare.getX(),redSquare.getY());
        }
    });

}
private void moveSquare(int x, int y) 
{
    final int CURR_X = redSquare .getX();
    final int CURR_Y = redSquare.getY();
    final int CURR_W = redSquare.getWidth();
    final int CURR_H = redSquare.getHeight();
    final int OFFSET = 1;

    // The square is moving, repaint background 
    // over the old square location. 
    repaint(CURR_X,CURR_Y,CURR_W+OFFSET,CURR_H+OFFSET);

    // Update coordinates.
    redSquare.setX(x+1);
    redSquare.setY(y+1);

    // Repaint the square at the new location.
    repaint(redSquare.getX(), redSquare.getY(), 
            redSquare.getWidth()+OFFSET, 
            redSquare.getHeight()+OFFSET);

}

如果我理解正确,您想单击某个位置,然后将正方形移到该位置,但是让正方形向该新位置移动某种动画。

您正在移动正方形并对其重新粉刷太快,以致似乎正方形仅从其初始位置移动到了新的最终位置。 您可以根据需要设置x和y像素的速度,并在循环中更新正方形的位置,以根据上一次循环迭代与x和y之间的间隔时间,将正方形移向最终点速度。

使用Swing Timer来安排动画。 阅读Swing教程中有关如何使用计时器的部分, 获取更多信息。

调用repaint不会立即导致组件被重画。 它只告诉渲染系统:“尽快重新粉刷该区域”。 但是渲染系统正忙于遍历for循环。

原因是mousePressed方法是由负责重新绘制的同一线程(即, Swing Event Dispatch Thread (EDT))执行的。 因此,该线程正在for循环中运行并触发重新绘制,但是只有完成for循环之后,它才能够实际执行重新绘制-然后,只有最后一个状态才可见。

这里的解决方案应该是在自己的线程中执行运动。 直接的解决方案可能看起来像这样

public void mousePressed(MouseEvent e) 
{   
    moveInOwnThread();
}

private void moveInOwnThread()
{
    Thread t = new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            move();
        }
    });
    t.setDaemon(true);
    t.start();
}

private void move()
{
    for(int i=0;i<10;i++)
    {
        moveSquare(redSquare.getX(),redSquare.getY());

        try
        {
            Thread.sleep(20);
        }
        catch (InterruptedException e)
        {
            Thread.currentThread().interrupt();
            return;
        }
    }
}

但是您应该阅读有关并发的一些知识: http : //docs.oracle.com/javase/tutorial/uiswing/concurrency/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM