我正在用JavaFX 2.2编写一个多线程的分形绘图程序,现在我需要一些指导。JavaFX:更新多任务的进度
我想要实现的是创建一个任务或服务(尚未决定),然后启动一些其他任务,实际完成计算和准备好时返回整个图像的部分。当所有部分返回到启动任务时,它将这些部分放在一起并将其返回到主线程,以便它可以可视化。
显然,所有这一切都必须发生,永远不会阻止用户界面。
问题是我找不出如何这些任务可以相互沟通。例如,我需要根据内部任务的平均进度(或类似的东西)更新启动任务的进度属性,因此他们的进度属性应该以某种方式绑定到启动任务的进度属性。图像块应放在一个列表或某个容器中,并在所有图像都可用时重新绘制在单独的图像上。
我已经写了一个简单的(但仍然是实验性的)这个程序的版本,只创建一个计算整个分形的任务。进度与GUI的进度条绑定。在任务成功时,返回值由EventHandler处理。
我不是要求一个完整的解决方案,但一些想法也许有一些示例代码会真的帮助我。
这是一个应该被修改的类:
package fractal;
import fractalUtil.DefaultPalette;
import fractalUtil.PaletteInterface;
import javafx.concurrent.Task;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import org.apache.commons.math3.complex.Complex;
/**
*
* @author athelionas
*/
public abstract class AbstractFractal extends Task implements FractalInterface {
private PaletteInterface palette;
protected final int width, height, order, iterations;
protected final double scale, xReal, xIm, xCenter, yCenter, zoom;
protected final boolean julia;
protected AbstractFractal(final int width, final int height, final double xReal, final double xIm, final double xCenter, final double yCenter, final int order, final boolean julia, final int iterations, final double zoom) {
this.width = width;
this.height = height;
this.xReal = xReal;
this.xIm = xIm;
this.xCenter = xCenter;
this.yCenter = yCenter;
this.order = order;
this.julia = julia;
this.iterations = iterations;
this.zoom = zoom;
this.scale = (double) width/(double) height;
palette = new DefaultPalette();
}
@Override
public final void setPalette(final PaletteInterface palette) {
this.palette = palette;
}
@Override
public abstract Complex formula(final Complex z, final Complex c, final int order, final Complex center);
@Override
public final Color calculatePoint(final Complex z, final Complex c, final int order, final Complex center, final int iterations) {
Complex zTemp = z;
int iter = iterations;
while (zTemp.abs() <= 2.0 && iter > 0) {
zTemp = formula(zTemp, c, order, center);
iter--;
}
if (iter == 0) {
return Color.rgb(0, 0, 0);
} else {
return palette.pickColor((double) (iterations - iter)/(double) iterations);
}
}
@Override
public final WritableImage call() {
Complex z;
Complex c;
Complex center = new Complex(xCenter, yCenter);
final WritableImage image = new WritableImage(width, height);
if (julia) {
c = new Complex(xReal, xIm);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
z = new Complex(((double) x)/(double) (width - 1) * 2.0 * scale * (1.0/zoom) - scale * (1.0/zoom), ((double) y)/(double) (height - 1) * 2.0 * (1.0/zoom) - 1.0 * (1.0/zoom));
image.getPixelWriter().setColor(x, y, calculatePoint(z, c, order, center, iterations));
}
}
} else {
z = new Complex(xReal, xIm);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
c = new Complex(((double) x)/(double) (width - 1) * 2.0 * scale * (1.0/zoom) - scale * (1.0/zoom), ((double) y)/(double) (height - 1) * 2.0 * (1.0/zoom) - 1.0 * (1.0/zoom));
image.getPixelWriter().setColor(x, y, calculatePoint(z, c, order, center, iterations));
}
updateProgress(y, height);
}
}
return image;
}
}
+1我忘了任务已经建好了。 –
非常感谢!这正是我几天来一直试图完成的事情。不幸的是这些文档相当稀少,所以再次感谢。现在我确信我可以自己找出其余的问题。 – Athelionas