我画的动画到挥杆的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上运行的大部分。
什么是下一个(小)的逻辑,我在这里采取的步骤?
更新:使用画布(不更新特技)显着地降低废绘制缓冲的图像的时间。 取而代之的是正对事件探查器的顶线,我无法找到它! 我可以做更多的比我要当我使用的面板。
编辑以更好的例子
从本质上讲,我们可以使用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);
}
}
}
}