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

问题描述 投票:4回答:2

[我正在尝试弄清楚如何为摆动组件设置动画,使其从点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();

            }
        });


    }

}

效果很好,只是我看起来有点断断续续。带有可拖动正方形的类似示例的运动(请参见Draggable Components in Java Swing)看起来更加平滑,因此我相信应该有一种方法可以使这种外观更好。任何建议将不胜感激。

java swing animation components
2个回答
4
投票

您正在为Swing库输入一个棘手的区域。但是,没有什么是不可能的。您可以使用Timer创建此类动画,但我确实建议您不要这样做。因此,您可以尽可能地移动组件,建议您使用Timing Framework库。

但是要注意:移动组件不是没有学习就应该做的。开发了秋千布局,以便按特定顺序放置组件。如果操纵尺寸和组件位置的值,将会破坏布局的功能,并且程序可能会以奇怪的方式运行。我曾经遇到过一些情况,就是我在不使用布局的情况下在Swing中开发了一个应用程序。在一个操作系统中,我的程序似乎可以正常运行,但是将其移植到其他系统时,一切都陷入混乱。因此,在Swing中启动具有此类自定义功能的应用程序之前,您需要保持关注并执行许多测试。

这是JavaFX技术出现在我们手中的原因之一。使用这种技术,我们可以减少工作量(在不同程序中部署应用程序),而做更多事情(包括遇到麻烦的程序)。考虑迁移到该技术。因此,您将看到JavaFX可以做什么,请下载演示程序Ensemble(搜索“ JavaFX演示和样本下载”)。作为学习来源,请开始here

如果这种选择对您来说太麻烦,请查看我给您提供的有关Timing Framework库的链接。在那里,您将找到Java代码示例,这些示例可以在各种Swing事物上以高性能使动画流畅。要学习如何使用该库,建议您阅读由Chet Haase和Romain Guy编写的书Filthy Rich Clients。尽管这本书已经过时,并且库代码中的内容已更改,但是您可以在library website上进行更新。就像我之前说的,下载库,还下载代码示例。随着时间的流逝,您将最终以最佳方式做自己想做的事情。

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


0
投票

这是我使用计时器对JComponent进行动画处理的方法。

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.