简单的Java Swing动画滞后

时间:2016-05-27 19:09:57

标签: java swing

我是一名初学者,我在制作简单的摇摆动画时遇到了麻烦。动画在运行时会滞后,除非发生其他事情,如鼠标移动或按下按键。我已经搜索了答案,但没有一个能解决这个问题。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Animation extends JPanel implements ActionListener {

    Timer timer = new Timer(5, this);
    int y = 0, velY = 2;

    public void actionPerformed(ActionEvent e) {

        y += velY;
        repaint();
    }

    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        g.setColor(Color.black);
        g.fillRect(50, y, 50, 50);

        timer.start();
    }

    public static void main(String[] args) {

        Animation drawPanel = new Animation();

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setVisible(true);
        frame.add(drawPanel);
    }
}

1 个答案:

答案 0 :(得分:5)

首先,获取paintComponent方法的timer.start() out ,因为它不属于那里,除了减慢渲染速度之外没有任何其他用途。相反,你应该只调用一次该方法,而只调用一次。

接下来,5 mSecs可能是一个不切实际的计时器延迟。尝试使用这个数字,但希望在接近10到15 mSecs的地方能够正常运行。

接下来,根据您测量的实际时间片差异来确定您的位置变化,而不是根据您希望计时器正在进行的操作。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Animation extends JPanel {
    private static final int TIMER_DELAY = 16;
    private static final double Y_VELOCITY = 0.05;
    private double dY = 0.0;
    private Timer timer = new Timer(TIMER_DELAY, new TimerListener());

    public Animation() {
        timer.start();
    }

    public void paintComponent(Graphics g) {

        super.paintComponent(g);

        g.setColor(Color.black);
        g.fillRect(50, (int) dY, 50, 50);
        // timer.start();
    }

    private class TimerListener implements ActionListener {
        private long prevTime;

        @Override
        public void actionPerformed(ActionEvent e) {
            if (prevTime == 0L) {
                repaint();
                prevTime = System.currentTimeMillis();
            } else {
                long currentTime = System.currentTimeMillis();
                long deltaTime = currentTime - prevTime;
                double deltaY = Y_VELOCITY * deltaTime;
                dY += deltaY;
                prevTime = currentTime;
                repaint();
            }

        }
    }

    public static void main(String[] args) {

        Animation drawPanel = new Animation();

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setVisible(true);
        frame.add(drawPanel);
    }
}