如何加快这一挥杆动画?(How do I speed up this swing animation

2019-06-26 19:44发布

我画的动画到挥杆的JPanel。 在1024×1024的屏幕被划分为2000件,其覆盖屏幕完全相同(无重叠)。

每一块是一个非常小的幅画面(它1 / 2000'th)的。 动画绘制一条每毫秒由被缓冲的图像在改变的像素和调用reaint()。 因此,在整个屏幕每2秒改变。 动画是在java.util.Timer中任务运行。

被缓冲的图像没有加速和不挥发的。 我将它的优先级为1。

框架根窗格被优化。 无论是正面和背面缓冲区加速,但不会挥发。

该工程确定。

剖析表明,几乎所有的grahics时间花在绘制缓冲图像正如人们所预料,用一些肮脏的矩形似乎并没有帮助减少油漆的时间。

如果我剪辑缓冲图像的绘制与它的确切形状,那块被画和屏幕的其余部分变白。

我想是有屏幕的其余部分留它的方式,只是有被剪辑得到的形状画。

使像素,每件需要混合10层,所以有一些计算完成那里。 可以/应该在这一个AWT计时器线程做更好?

或者我应该用画布和更新伎俩http://java.sun.com/products/jfc/tsc/articles/painting/src/UpdateDemo.java

我所看到的建议,包括Toolkit.getDefaultToolkit()setDynamicLayout(真)。 System.setProperty( “sun.awt.noerasebackground”, “真”);

其他建议包括paintimmedialtely,子类的JComponent而不是JPanel的。

我觉得这一切有点混乱。

我想保持这种独立于操作系统的尽可能多的,但应用程序将在Windows 7上运行的大部分。

什么是下一个(小)的逻辑,我在这里采取的步骤?

更新:使用画布(不更新特技)显着地降低废绘制缓冲的图像的时间。 取而代之的是正对事件探查器的顶线,我无法找到它! 我可以做更多的比我要当我使用的面板。

Answer 1:

这里有几个建议:

  • 严格审查需要repaint()每毫秒; 特别是,如果看到一些更新可能被合并。

  • 考虑方便java.swing.Timer ,这使得在EDT和支持合并事件。

  • 调用drawImage()是最快的,不需要标度的情况下,如本AnimationTest

  • 总是预先计算图像尽可能,如在本建议KineticModel示出几个动画技术。

  • TexturePaint ,在使用KineticModel ,也显示在这里 。

  • IndexColorModel ,说明这里 ,可以适用。

  • 一个SSCCE将让你的各种方法更容易剖析隔离。



Answer 2:

编辑以更好的例子

从本质上讲,我们可以使用RepaintManager跟踪/更新,我们改变每毫秒的几个像素。 脏区将累积,直到油漆实际上是能够发生的。 当涂料发生,它采用了paintImmediately(int x, int y, int w, int h)功能(除非整个部件脏了) -所以我们只更新图像的一小部分脱身。 希望这些示例代码不依赖于操作系统的 - 让我知道,如果它不为你工作。

import java.awt.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class UpdatePane extends JPanel{
    final int MAX = 1024;

    //The repaint manager in charge of determining dirty pixels
    RepaintManager paintManager = RepaintManager.currentManager(this);

    //Master image
    BufferedImage img = new BufferedImage(MAX, MAX, BufferedImage.TYPE_INT_RGB);


    @Override
    public void paintComponent(Graphics g){
        g.drawImage(img, 0, 0, null);
    }

    public void paintImmediately(int x, int y, int w, int h){
        BufferedImage img2 = img.getSubimage(x, y, w, h);
        getGraphics().drawImage(img2, x, y, null);
    }

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                final UpdatePane outside = new UpdatePane(); 

                outside.setPreferredSize(new Dimension(1024,1024));

                JFrame frame = new JFrame();
                frame.add(outside);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);

                outside.new Worker().execute();
            }
        });
        }

    //Goes through updating pixels (like your application would)
    public class Worker extends SwingWorker<Integer, Integer>{
        int currentColor = Color.black.getRGB();
        public int x = 0;
        public int y = 0;
        @Override
        protected Integer doInBackground() throws Exception {
            while(true){
                if(x < MAX-1){
                    x++;
                } else if(x >= MAX-1 && y < MAX-1){
                    y++;
                    x = 0;
                } else{
                    y = 0;
                    x = 0;
                }

                if(currentColor < 256){
                    currentColor++;
                } else{
                    currentColor = 0;
                }

                img.setRGB(x, y, currentColor); 

                //Tells which portion needs to be repainted [will call paintImmediately(int x, int y, int w, int h)]
                paintManager.addDirtyRegion(UpdatePane.this, x, y, 1, 1);
                Thread.sleep(1);
            }
        } 

    }
}


文章来源: How do I speed up this swing animation?