Java Swing:如何平滑地设置/移动组件的动画

Java Swing:如何平滑地设置/移动组件的动画,java,swing,animation,components,Java,Swing,Animation,Components,我试图弄清楚如何设置一个摆动组件从a点到b点的动画。下面是一个使红色JPanel从左向右移动的小代码示例: import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class Movi

我试图弄清楚如何设置一个摆动组件从a点到b点的动画。下面是一个使红色JPanel从左向右移动的小代码示例:


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

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

public class MovingSquareExample {

    private static final JPanel square = new JPanel();
    private static int x = 20;

    public static void createAndShowGUI(){
        JFrame frame = new JFrame();
        frame.getContentPane().setLayout(null);
        frame.setSize(500,500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(square);
        square.setBounds(20,200,100,100);
        square.setBackground(Color.RED);

        Timer timer = new Timer(1000/60,new MyActionListener());
        timer.start();
        frame.setVisible(true);
    }

    public static class MyActionListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent arg0) {
            square.setLocation(x++, 200);

        }

    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                createAndShowGUI();

            }
        });


    }

}

它很好用,只是我看起来有点颠簸。类似的例子中,有一个可拖动的正方形(请参阅)的运动看起来更平滑,所以我认为应该有办法让它看起来更好。如有任何建议,将不胜感激

您正在进入Swing库的一个棘手区域。然而,没有什么是不可能的。您可以使用计时器创建这样的动画,但我真的建议您不要这样做。因此,您可以尽可能最好地移动组件,我建议您使用该库

但请注意:移动组件不应在未经研究的情况下制作。开发了Swing布局,以便按特定顺序放置组件。如果你操纵这些值​​对于组件的尺寸和定位,您将破坏布局的功能,并且您的程序可能以奇怪的方式运行。我曾经在Swing中开发过一个应用程序,但没有使用布局。在一个操作系统中,我的程序似乎工作正常,但将其移植到其他系统时,一切都变得混乱。因此,在Swing中启动具有此类定制的应用程序之前,您需要保持调优并执行许多测试

这就是JavaFX技术进入我们手中的原因之一。有了这样的技术,我们可以少做一些事情(将应用程序部署到不同的程序中),多做一些事情(包括遇到问题的部分)。考虑迁移到该技术。下载演示程序,看看JavaFX能做什么。如果你对这项技术感兴趣,我建议你开始学习它。如果你不想下载这个演示,你也可以在网上找到演示它是如何工作的

如果这个替代方案对您来说太难了,请查看我给您的关于计时框架库的链接。在这里,您将找到一些Java代码示例,这些代码可以在各种Swing对象上以高性能制作平滑的动画。为了学习如何使用这个图书馆,我建议你去拿这本书,由切特·哈斯和罗曼·盖伊写的。尽管这本书已经过时,并且库代码中的内容已经更改,但是您可以在上获得更新。正如我前面所说的,下载库,并下载代码示例。随着时间的推移,你最终会以最好的方式做你想做的事情


我希望你能完成你想要的。祝你好运

下面是我使用计时器制作JComponents动画的方法

private void animate(JComponent component, Point newPoint, int frames, int interval) {
    Rectangle compBounds = component.getBounds();

    Point oldPoint = new Point(compBounds.x, compBounds.y),
          animFrame = new Point((newPoint.x - oldPoint.x) / frames,
                                (newPoint.y - oldPoint.y) / frames);

    new Timer(interval, new ActionListener() {
        int currentFrame = 0;
        public void actionPerformed(ActionEvent e) {
            component.setBounds(oldPoint.x + (animFrame.x * currentFrame),
                                oldPoint.y + (animFrame.y * currentFrame),
                                compBounds.width,
                                compBounds.height);

            if (currentFrame != frames)
                currentFrame++;
            else
                ((Timer)e.getSource()).stop();
        }
    }).start();
}

看起来还算不错,不过速度有点慢。您可以尝试使用
1000/25
作为延迟,并增加
x
增量。记住,动画是一种错觉。还记得,Swing使用一个被动渲染引擎,所以当Swing决定他们也应该考虑移动一个形状而不是一个组件时,会发生更新。1美元。