我有一个小问题。在动画期间执行方法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。对不起我的英语不好,这不是我的第一语言。
答案 0 :(得分:1)
每次生成新的背景图像然后模糊它时,没有通用的方法来解决这个问题。 GaussianBlur 是一个缓慢的操作,句号。
如果 AnotherClass.getBgImage()从预定义的图像集传递图像,则将模糊一次应用于集合中的每个图像问题消失了。
如果您动态地在AnotherClass.getBgImage()中创建图像,那么可能能够通过更改图像创建来加速它以创建模糊图像开始。根据创建图像所做的操作,这可能是可行的,也可能是不可行的。
如果上述两种方法都没有解决,则需要研究其他选项以生成更快的模糊图像;有更简单的模糊方法,通常更快,但看起来有点像高斯。
你看,这一切归结为在性能关键路径上反复调用GaussianBlur。
答案 1 :(得分:1)
您要做的最好的事情是在paint方法之外进行图像更新,并且只在新图像准备就绪时重绘。获取现有代码,并为图像添加持久性引用,该引用将被绘制到JComponent
每个绘制方法上。然后让你的动画计时器执行高斯模糊并更新你的图像。
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...
}
}
答案 2 :(得分:0)
你应该从画家那里提取逻辑。画家被称为有约束力,应该执行得非常快。
BufferedImage bgImage = GraphicsUtils.gaussianBlur(AnotherClass.getBgImage());
这条线必须每次都执行?也许你可以使用一个字段来存储图像,画家可以只是图像,而不是每次都应用高斯布尔。
试试这个: 公共类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...
}
}