Can';无法在Java中获得普通动画(图仅出现在另一个位置,不会滑动)
我这里有个问题。下面的程序创建一个动画(从一个点到另一个点的圆)。单击按钮时,动画应开始 问题是当我点击按钮时,我看不到圆圈在滑动。它只是在一段时间后出现在另一个地方 我(作为初学者)似乎很感兴趣,如果我不使用按钮,并在go()内调用moveIt()方法,我会得到一个正常的动画(我可以看到圆圈滑动) 你能就这个问题给我一些建议吗 谢谢 节目如下:Can';无法在Java中获得普通动画(图仅出现在另一个位置,不会滑动),java,swing,animation,Java,Swing,Animation,我这里有个问题。下面的程序创建一个动画(从一个点到另一个点的圆)。单击按钮时,动画应开始 问题是当我点击按钮时,我看不到圆圈在滑动。它只是在一段时间后出现在另一个地方 我(作为初学者)似乎很感兴趣,如果我不使用按钮,并在go()内调用moveIt()方法,我会得到一个正常的动画(我可以看到圆圈滑动) 你能就这个问题给我一些建议吗 谢谢 节目如下: import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphi
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();
}
}
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Graphics;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JButton;
导入java.awt.event.*;
最后一个公共类minimiMusicLayer1实现ActionListener
{
JFrame框架;
拖板拖板;
私有整数X=7;
私人智力Y=7;
公共静态void main(字符串…参数)
{
新的MiniMiniMusicPlayer1().go();
}
私人空间
{
帧=新的JFrame(“播放器”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawPanel=新的drawPanel();
frame.getContentPane().add(BorderLayout.CENTER,drawPanel);
JButton buttonStart=新JButton(“开始动画”);
frame.getContentPane().add(BorderLayout.SOUTH,buttonStart);
buttonStart.addActionListener(此);
frame.setresizeable(false);
框架。设置尺寸(300300);
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
@凌驾
已执行的公共无效操作(操作事件ev){
moveIt();
}
类DrawPanel扩展了JPanel
{
公共组件(图形g)
{
g、 设置颜色(颜色为黑色);
g、 fillRect(0,0,this.getWidth(),this.getHeight());
g、 setColor(Color.RED);
g、 椭圆形(X,Y,50,50);
}
}
私有无效移动IT()
{
对于(int i=0;i<100;++i)
{
X++;
Y++;
尝试
{
睡眠(10);
}
捕获(例外e)
{
e、 printStackTrace();
}
frame.repaint();
}
}
}
Swing和AWT使用事件调度线程工作。该线程负责处理所有事件(运行事件处理程序,例如按钮的actionPerformed
)和重新绘制请求
当您从go
运行moveIt
时,它由主线程运行。它创建重绘请求,与主线程并发运行的事件分派线程分派这些请求。因此,您可以看到动画
但是,当您从事件处理程序调用moveIt
时,它将由事件调度线程本身运行。因此,执行整个循环,所有重绘请求排队,但线程很忙,在循环完成之前无法调度它们
完成循环后,它将分派重新绘制(或者更确切地说,它只分派一个,不需要重新绘制100次)。如果最终状态为X和Y,则重新绘制完成
如果要查看动画,应确保未在EDT中运行动画。例如,您可以为此使用对象
记住永远不要在事件处理程序中运行长操作。它会阻塞EDT并使GUI无响应。切勿在事件处理程序中使用
Thread.sleep()
。如果您的长任务应该定期执行,请使用计时器。如果它应该执行一些大任务,比如从数据库加载,那么使用SwingWorker
Swing和AWT工作,使用事件调度线程。该线程负责处理所有事件(运行事件处理程序,例如按钮的actionPerformed
)和重新绘制请求
当您从go
运行moveIt
时,它由主线程运行。它创建重绘请求,与主线程并发运行的事件分派线程分派这些请求。因此,您可以看到动画
但是,当您从事件处理程序调用moveIt
时,它将由事件调度线程本身运行。因此,执行整个循环,所有重绘请求排队,但线程很忙,在循环完成之前无法调度它们
完成循环后,它将分派重新绘制(或者更确切地说,它只分派一个,不需要重新绘制100次)。如果最终状态为X和Y,则重新绘制完成
如果要查看动画,应确保未在EDT中运行动画。例如,您可以为此使用对象
记住永远不要在事件处理程序中运行长操作。它会阻塞EDT并使GUI无响应。切勿在事件处理程序中使用Thread.sleep()
。如果您的长任务应该定期执行,请使用计时器。如果它应该执行一些大任务,比如从数据库加载,请使用SwingWorker