【问题标题】:Java Swing: how to smoothly animate/move componentJava Swing:如何平滑地动画/移动组件
【发布时间】:2014-02-10 10:27:45
【问题描述】:

我试图弄清楚如何为摆动组件设置动画以从 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)的运动看起来更平滑,所以我相信应该有一种方法可以让这个看起来更好。任何建议将不胜感激。

【问题讨论】:

  • 看起来还不错,只是有点慢。您可以尝试使用1000/25 延迟并增加x 增量。请记住,动画是一种幻觉。还要记住,Swing 使用被动渲染引擎,所以当 Swing 决定应该更新时就会发生更新
  • 还可以考虑移动一个形状而不是一个组件,对于example; +1 Minimal, Complete, Valid Example

标签: java swing animation components


【解决方案1】:

您正在进入 Swing 库的一个棘手领域。然而,没有什么是不可能的。你可以使用 Timer 创建这样的动画,但我真的不建议你这样做。所以你可以尽可能地移动组件,我建议你使用Timing Framework库。

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

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

如果这个替代方案对你来说太费力了,请查看我给你的关于 Timing Framework 库的链接。在那里,您将找到 Java 代码示例,这些代码可以在各种 Swing 事物上以高性能制作流畅的动画。要了解如何使用这个库,我建议您获取由 Chet Haase 和 Romain Guy 编写的书 Filthy Rich Clients。虽然这本书已经过时并且图书馆代码中的内容已经更改,但您可以在library website 上获得更新。正如我之前所说,下载库,并下载代码示例。随着时间的推移,你最终会以最好的方式做你想做的事。

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

【讨论】:

    【解决方案2】:

    这是我使用计时器制作 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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 2015-02-25
      • 1970-01-01
      相关资源
      最近更新 更多