Swing Worker:函数 get() [英] Swing Worker : function get()

查看:32
本文介绍了Swing Worker:函数 get()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是我不明白 swingworker 是如何工作的,因为我想做的是使 fa=worker.get() 因为我有一个很长的方法来计算在后台运行的很多点,因为我不想冻结我的界面,我想让她的结果来绘制组件图像.但是当我执行 fa=worker.get() 时我不明白它去哪里了,因为我的控制台打印 "titi" 并且我放了很多其他打印来查看程序的下一部分到达但没有打印出来.请帮助我了解在 get() 之后或执行时编译的位置,如果您知道如何实现我需要的内容,欢迎使用每个代码块.

My problem is that I don't understand how the swingworker works because what I'm trying to do is to make fa=worker.get() because I have a long method which compute a lot of points running in background because I don't want to freeze my interface and I want to get her results to paint the component image. But I don't understand where it goes when I do fa=worker.get() because my console prints "titi" and I put a lot of other printing to see the next part of program reached but no one is printed. Please help me to know where the compilation goes after get() or while it execute it and if you have an idea of how to implements what I need every block of code is welcome.

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() 上,你应该 publish() 中间结果和 process() 他们在 EDT 上,对于示例.

Instead of blocking on get(), you should publish() intermediate results and process() them on the EDT, for example.

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

Addendum: It looks like you're trying to simulate flame using a fractal approach. Because this may be computationally expensive, it may be useful to construct the image as a TexturePaint, which can be used to fill any Shape in a Graphics context. In the example, a SwingWorker<TexturePaint, TexturePaint> publishes a simple sequence of frames at an artificial rate of ~25Hz. Because process() executes on the EDT, it's safe to reference each new paint in updating the 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();
            }
        });
    }
}

这篇关于Swing Worker:函数 get()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆