我想在点击鼠标后重新绘制正方形,但重新绘制方法将被调用10次。
例如,正方形在x,y中,鼠标点击后将重新绘制:
我尝试将重绘方法循环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);
}
答案 0 :(得分:2)
如果我理解正确,你想点击某个地方,并让方块移动到那里,但让方块有一些类型的移动动画朝这个新位置。
你正在移动你的方块并重新绘制它太快,以至于看起来好像广场只是从它的初始位置移动到它的新的最终位置。您可以根据需要设置x和y像素速度,并在一个循环中更新正方形的位置,该循环将正方形移向它想要的最终位置,这取决于最后一次循环迭代与x和y之间经过的时间的速度。
答案 1 :(得分:2)
使用Swing Timer
来安排动画。有关详细信息,请阅读How to Use Timers上的Swing教程中的部分。
答案 2 :(得分:1)
对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/