我在GUI中创建了一个着名的Mandelbrot Fractal,为了加快创建我的形象,我决定使用Swing Workers。在doInBackground()方法中,我正在计算每个像素的颜色,我将所有颜色都放入数组中。在方法done()中,我访问数组并用适当的颜色为每个像素着色。这样,在EDT中进行着色时,在不同的线程中进行繁重的计算。我只有一个问题 - 准备好的图片没有显示,即使我知道它们存储在BufferedImage中(我可以将文件保存到我的硬盘上,直接访问BufferedImage,或者 - 缩放时 - 我正在创建一个深拷贝一个BufferedImage - 在这种情况下,我可以看到正确的图像)。我是Java的新手,但我希望我的应用程序尽可能好。我的代码位于以下位置:http://pastebin.com/M2iw9rEY
public abstract class UniversalJPanel extends JPanel{
protected BufferedImage image;
protected Graphics2D g2d;
protected int iterations = 100; // max number of iterations
protected double realMin = -2.0; // default min real
protected double realMax = 2.0;// default max real
protected double imaginaryMin = -1.6; // default min imaginary
protected double imaginaryMax = 1.6;// default max imaginary
protected int panelHeight;
protected int panelWidth;
protected Point pressed, released; // points pressed and released - used to calculate drawn rectangle
protected boolean dragged; // if is dragged - draw rectangle
protected int recWidth, recHeight,xStart, yStart; // variables to calculate rectangle
protected FractalWorker[] arrayOfWorkers; // array of Swing workers
public abstract int calculateIterations(Complex c);
public abstract double getDistance(Complex a, Complex b);
public void paintComponent(Graphics g){
super.paintComponent(g);
panelHeight = getHeight();
panelWidth = getWidth();
image =new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); // creating new Bufered image
g2d= (Graphics2D) image.getGraphics();
arrayOfWorkers= new FractalWorker[getHeight()]; // create new worker for each row and execute them
for(int q = 0; q < getHeight(); q++ ){
arrayOfWorkers[q] = new FractalWorker(q);
arrayOfWorkers[q].execute();
}
g.drawImage(image, 0, 0, null); // draw an image
}
// *** getters, setters, different code//
private class FractalWorker extends SwingWorker<Object, Object>{
private int y; // row on which worker should work now
private Color[] arrayOfColors; // array of colors produced by workers
public FractalWorker( int z){
y = z;
}
protected Object doInBackground() throws Exception {
arrayOfColors = new Color[getWidth()];
for(int q=0; q<getWidth(); q++){ // calculate and insert into array proper color for given pixel
int iter = calculateIterations(setComplexNumber(new Point(q,y)));
if(iter == iterations){
arrayOfColors[q] = Color.black;
}else{
arrayOfColors[q] = Color.getHSBColor((float)((iter/ 20.0)), 1.0f, 1.0f );
}
}
return null;
}
protected void done(){ // take color from the array and draw pixel
for(int i = 0; i<arrayOfColors.length; i++){
g2d.setColor(arrayOfColors[i]);
g2d.drawLine(i, y, i, y);
}
}
}
答案 0 :(得分:0)
调用g.drawImage(...)时,图像的当前内容将被绘制到组件中。此时SwingWorkers没有完成他们的工作,因为你在drawImage调用之前立即启动它们。你不应该在paintComponent方法中启动SwingWorkers,如果收到了一个绘制请求,那么启动一个很长的绘制过程为时已晚。
更好的解决方案可能是在程序启动时创建BufferedImage,然后在组件大小更改时重新创建它。然后,每当需要重绘时,您应该启动SwingWorkers,并在完成绘制时调用组件上的repaint()。