Swing Worker:function get()
我的问题是,我不明白swingworker
是如何工作的,因为我正在做的是使fa=worker.get()
因为我有一个很长的方法,计算很多点在后台运行,因为我不'我想冻结我的界面,我想让她的结果来绘制组件图像。 但是,我不明白它在哪里去,当我做fa=worker.get()
因为我的控制台打印"titi"
,我把很多其他打印看到程序的下一部分到达,但没有人打印。 请帮助我知道在get()
或执行它之后编译的位置,以及如果您对如何实现我所需要的每个代码块有所了解,欢迎。
public void paintComponent(final Graphics g1){ // TODO Auto-generated method stub final int width=getWidth(); final int height=getHeight(); image= new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //On transforme le rectangle de base en un rectangle qui a le meme ratio que le cadre contenant l'ancien //(Il yaura dessus la meme fractale mais avec plus de fond noir) afin que l'on puisse zoomer sans deformer la fractale frame = frame.expandToAspectRatio((double)getWidth()/getHeight()); FlameAccumulator fa=null; worker= new SwingWorker<FlameAccumulator,FlameAccumulator>(){ @Override protected FlameAccumulator doInBackground() throws Exception { // TODO Auto-generated method stub System.out.println("exception"); return builder.build().compute(frame,width,height,density); } }; try { System.out.println("titi"); fa=worker.get(); } catch (InterruptedException | ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } Graphics g0=(Graphics2D)g1; if(fa==null){ System.out.println("toto"); for (int i = 0; i <height; i++) { for (int j = 0; j < width; j++) { image.setRGB(j,i,0); } } } else{ System.out.println("tata"); for (int i = 0; i <height; i++) { for (int j = 0; j < width; j++) { image.setRGB(j,i,fa.color(palette, background, j, height-1-i).asPackedRGB()); } } } g0.drawImage(image,0,0,null); }
例如,不要在get()
上阻塞,而应该在EDT上publish()
中间结果并process()
它们。
附录:看起来你正在尝试使用分形方法模拟火焰 。 因为这可能在计算上是昂贵的,所以将图像构造为TexturePaint
可能是有用的,该TexturePaint
可以用于填充Graphics
上下文中的任何Shape
。 在这个例子中,一个SwingWorker<TexturePaint, TexturePaint>
以SwingWorker<TexturePaint, TexturePaint>
的人为速率发布一个简单的帧序列。 因为process()
在EDT上执行,所以在更新TexturePanel
引用每个新的paint是安全的。
import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.TexturePaint; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import java.util.List; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingWorker; /** * @see https://stackoverflow.com/a/16880714/230513 */ public class HeatTest { private static final int N = 256; private TexturePanel p = new TexturePanel(); private void display() { JFrame f = new JFrame("HeatTest"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(p); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); new HeatWorker().execute(); } private class TexturePanel extends JPanel { private TexturePaint paint; public void setTexture(TexturePaint tp) { this.paint = tp; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setPaint(paint); g2d.fillRect(0, 0, getWidth(), getHeight()); } @Override public Dimension getPreferredSize() { return new Dimension(N, N); } } private class HeatWorker extends SwingWorker<TexturePaint, TexturePaint> { private final Random random = new Random(); @Override protected TexturePaint doInBackground() throws Exception { BufferedImage image = new BufferedImage(N, N, BufferedImage.TYPE_INT_ARGB); TexturePaint paint = new TexturePaint(image, new Rectangle(N, N)); int[] iArray = {0, 0, 0, 255}; while (true) { WritableRaster raster = image.getRaster(); for (int row = 0; row < N; row++) { for (int col = 0; col < N; col++) { iArray[0] = 255; iArray[1] = (int) (128 + 32 * random.nextGaussian()); iArray[2] = 0; raster.setPixel(col, row, iArray); } } publish(paint); Thread.sleep(40); // ~25 Hz } } @Override protected void process(List<TexturePaint> list) { for (TexturePaint paint : list) { p.setTexture(paint); p.repaint(); } } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new HeatTest().display(); } }); } }
你不应该在paintComponent()
方法中调用get()
。 这将阻止并等待工作人员完成其计算。 get()应该只在worker的done()
方法中被调用,当你确定worker已经完成了它的计算之后,如文档中的示例所示。