我有个小问题。在动画期间执行paintComponent()方法时,我必须不断更新变量bgImage。但这需要很长的时间,这样动画就会慢下来。
问题的代码块:
public class ProblemClass extends JComponent {
    private static final int FRAME_FREQUENCY = 30;
    private final Timer animationTimer;
    public ProblemClass() {
        this.animationTimer = new Timer(1000 / FRAME_FREQUENCY, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                repaint(); // When the animation started is often invoked repaint()
            }
        });
    }
    // Other code...
    /** 
     * Start animation from another class
     */
    public void startAnimation() {
        this.animationTimer.start();
    }
    @Override 
    protected void paintComponent(Graphics g) { 
        // GraphicsUtils.gaussianBlur(...) it's a long-time operation
        BufferedImage bgImage = GraphicsUtils.gaussianBlur(AnotherClass.getBgImage()); 
        g2.drawImage(bgImage, 0, 0, null); 
        // Other code...
    }
}我在互联网上读到,我需要在并行线程(SwingWorker)中运行长任务,但我不知道如何在我的情况下这样做。我该如何解决这个问题?
P.S.对不起我的英语不好,这不是我的第一语言。
发布于 2014-09-17 16:46:52
您要做的最好的工作是在update方法之外进行图像更新,并且只在新图像准备好时重新绘制。取现有代码,并向图像添加一个持久引用,该引用将被绘制到JComponent reference方法上。然后让你的动画定时器做高斯模糊和更新你的图像。
public class ProblemClass extends JComponent {
    private static final int FRAME_FREQUENCY = 30;
    private final Timer animationTimer;
    //persistent reference to the image
    private BufferedImage bgImage;
    public ProblemClass() {
        this.animationTimer = new Timer(1000 / FRAME_FREQUENCY, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //Update the image on each call before repainting
                bgImage = GraphicsUtils.gaussianBlur(AnotherClass.getBgImage());
                repaint();
            }
        });
    }
    /** 
     * Start animation from another class
     */
    public void startAnimation() {
        this.animationTimer.start();
    }
    @Override
    protected void paintComponent(Graphics g2) {
        g2.drawImage(bgImage, 0, 0, null);
        // Other code...
    }
}发布于 2014-09-17 16:38:54
当你每次生成一个新的背景图像,然后模糊它时,没有通用的方法来解决这个问题。GaussianBlur是一个缓慢的操作,周期。
如果AnotherClass.getBgImage()从一组预定义的图像中传递图像,那么对集合中的每个图像应用一次模糊处理,问题就会消失。
如果您在AnotherClass.getBgImage()中动态创建图像,那么您可以通过更改图像创建从一开始就创建模糊图像来加快它的速度。根据创建图像所做的工作,这可能是可行的,也可能是不可行的。
如果上述两种方法都没有效果,则需要研究其他选项,以生成速度更快的模糊图像;还有一些简单的模糊方法,它们通常更快,但看起来有点类似于高斯。
您可以看到,这一切归根结底是摆脱了在性能关键路径上反复调用GaussianBlur。
发布于 2014-09-17 16:18:15
你应该从画家那里提取逻辑。画家被明确地称为,应该执行得非常快。
  BufferedImage bgImage = GraphicsUtils.gaussianBlur(AnotherClass.getBgImage()); 这行每次都要执行吗?也许您可以使用一个字段来存储图像,而画家可以只是暂停图像,而不是每次应用gaussianBlur。
尝试如下:公共类ProblemClass扩展JComponent {
    private static final int FRAME_FREQUENCY = 30;
    private final Timer animationTimer;
    private final BufferedImage bgImage;
    public ProblemClass() {
        bgImage = GraphicsUtils.gaussianBlur(AnotherClass.getBgImage());
        this.animationTimer = new Timer(1000 / FRAME_FREQUENCY, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                repaint(); // When the animation started is often invoked repaint()
            }
        });
    }
        // Other code...
    /** 
     * Start animation from another class
     */
    public void startAnimation() {
        this.animationTimer.start();
    }
    @Override
    protected void paintComponent(Graphics g2) {
        // GraphicsUtils.gaussianBlur(...) it's a long-time operation
        g2.drawImage(bgImage, 0, 0, null);
        // Other code...
    }
}https://stackoverflow.com/questions/25895498
复制相似问题