java - Java中无法获得正常的动画(人物只是出现在另一个地方,不滑动)

标签 java swing animation

我这里遇到了一个问题。下面的程序创建一个动画(从一个点到另一个点的圆圈)。单击按钮时动画应开始。

问题是,当我单击按钮时,我看不到圆圈滑动。它只是在一段时间后出现在其他地方。

对我来说(作为初学者)似乎很有趣,如果我不使用按钮,并在 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/

相关文章:

java - 在 Java 9 中使用必需参数和可选参数构建抽象父类(super class)的子类对象的最佳方法是什么?

javascript - 动画 GIF 作为 THREE.js 中的纹理

java - 如何使两个复选框在 Swing 中并排放置?

jquery - 在 javascript 动画上 append html

html - css动画中的反变换

java - 如何使用 View 解析器返回移动或普通 View ?

java - 如何在其调用者线程上调用接口(interface)回调?

java - Java 8 中方法引用的外部参数

java - 调整大小时 jpanel 与 jdesktop Pane 不匹配

Java Swing 重/慢 paintComponent - 有什么建议吗?