我这里遇到了一个问题。下面的程序创建一个动画(从一个点到另一个点的圆圈)。单击按钮时动画应开始。
问题是,当我单击按钮时,我看不到圆圈滑动。它只是在一段时间后出现在其他地方。
对我来说(作为初学者)似乎很有趣,如果我不使用按钮,并在 go() 中调用 moveIt() 方法,我获得正常的动画(我可以看到圆圈滑动)。
您能给我一些关于这个问题的建议吗?
谢谢。
这是程序:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.event.*;
final public class MiniMiniMusicPlayer1 implements ActionListener
{
JFrame frame;
DrawPanel drawPanel;
private int X = 7;
private int Y = 7;
public static void main(String... args)
{
new MiniMiniMusicPlayer1().go();
}
private void go()
{
frame = new JFrame("Player");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawPanel = new DrawPanel();
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
JButton buttonStart = new JButton("Start animation");
frame.getContentPane().add(BorderLayout.SOUTH, buttonStart);
buttonStart.addActionListener(this);
frame.setResizable(false);
frame.setSize(300, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent ev){
moveIt();
}
class DrawPanel extends JPanel
{
public void paintComponent(Graphics g)
{
g.setColor(Color.BLACK);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.RED);
g.fillOval(X, Y, 50, 50);
}
}
private void moveIt()
{
for (int i = 0; i < 100; ++i)
{
X++;
Y++;
try
{
Thread.sleep(10);
}
catch (Exception e)
{
e.printStackTrace();
}
frame.repaint();
}
}
}
最佳答案
Swing 和 AWT 使用事件调度线程工作。该线程负责处理所有事件(运行事件处理程序,例如按钮的 actionPerformed
)和重绘请求。
当您从 go
运行 moveIt
时,它由主线程运行。它创建重绘请求,并由与主线程同时运行的事件调度线程来调度它们。这样,您就可以看到动画了。
但是当您从事件处理程序调用 moveIt
时,它由事件分派(dispatch)线程本身运行。因此,整个循环被执行,所有重绘请求都被排队,但线程很忙,在完成循环之前无法调度它们。
当循环完成时,它会调度重绘(或者更确切地说,它只调度一次,不需要重绘 100 次)。重绘已根据 X 和 Y 的最终状态完成。
如果您想观看动画,您应该确保您没有在 EDT 内运行它们。您可以使用 javax.swing.Timer
例如,此对象。
记住永远不要在事件处理程序中运行长时间操作。它会阻止 EDT 并使您的 GUI 无响应。切勿在事件处理程序中使用 Thread.sleep() 。如果您的长任务需要定期执行某些操作,请使用计时器
。如果需要执行一些大型任务(例如从数据库加载),请使用 SwingWorker
。
关于java - Java中无法获得正常的动画(人物只是出现在另一个地方,不滑动),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35942833/