2

我的问题是我不明白它是如何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);
        }
4

2 回答 2

8

例如get(),您应该在 EDT 上进行publish()中间结果和它们,而不是阻塞在.process()

附录:看起来您正在尝试使用分形方法模拟火焰。因为这可能在计算上很昂贵,所以将图像构造为 a 可能很有用TexturePaint,它可用于填充上下文Shape中的任何内容Graphics。在示例中,aSwingWorker<TexturePaint, TexturePaint>以 ~25Hz 的人工速率发布了一个简单的帧序列。因为process()在 EDT 上执行,所以在更新TexturePanel.

图片

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();
            }
        });
    }
}
于 2013-06-02T07:27:53.887 回答
3

您不应该调用get()paintComponent()方法。这将阻塞并等待工作人员完成其计算。get() 应该只在您的工作人员的done()方法中调用,当您确定工作人员已完成其计算时,如文档中包含的示例所示。

于 2013-06-02T07:27:53.933 回答