SwingWorker 和 JProgressBar 的问题 [英] Issues with SwingWorker and JProgressBar

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

问题描述

我需要将给定的任何图像转换为字节数组以满足加密要求.我正在使用 JProgressBar 来监视转换进度,以防所选图像很大:

I need to convert a any image given to a byte array for encryption requirement. I'm using JProgressBar to monitor the conversion progress in case the chosen image is large:

File p= new File("C:");
BufferedImage oImg = ImageIO.read(p);
ByteArrayOutputStream ba = new ByteArrayOutputStream();
ImageIO.write(oImg, "jpg", ba);
ba.flush();

ProgressBar pb = new ProgressBar();
Thread thread = new Thread(pb);
thread.join();
pb.fireTask(ba.toByteArray());

我定义了一个使用 SwingWorkerProgressBar 类,如下所示:

I defined a ProgressBar class that uses SwingWorker as follows:

public class ProgressBar extends JPanel implements Runnable {

    private JProgressBar progressBar;
    private Task task;
    private byte[] imgByteArray;


    public void run() {
        createGUI();
    }

    // Create the GUI
    private void createGUI() {

        JFrame frame = new JFrame("Converting...");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JComponent newContentPane = new ProgressBar();
        newContentPane.setOpaque(true); 
        frame.setContentPane(newContentPane);

        JPanel panel = new JPanel();
        progressBar = new JProgressBar(0, 100);
        progressBar.setBounds(20, 22, 419, 20);
        progressBar.setValue(0);
        progressBar.setStringPainted(true);
        panel.add(progressBar);
        add(panel);
        setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        frame.pack();
        frame.setVisible(true);
    }


    /**
     * Firing the Task
     */
    public void fireTask(byte[] imgArray) {
        System.arraycopy(imgArray, 0, imgByteArray, 0, imgByteArray.length);
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        task = new Task();
        task.execute();
    }



    class Task extends SwingWorker<Void, Void> {
        @Override
        public Void doInBackground() {

            for (int i=0; i<=imgByteArray.length; i++){ 

                progressBar.setValue(i); 
                progressBar.repaint(); 
                try{
                    Thread.sleep(50);
                } catch (InterruptedException err){
                }
            }
            return null;
        }

           public void done() {
               Toolkit.getDefaultToolkit().beep();
               setCursor(null); // turn off the wait cursor
               }
        }
}

很遗憾,发生了这个错误!

Sadly, this error occurs!

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at ciphers.ProgressBar.fireTask(ProgressBar.java:65)
    at ciphers.Images.imageEncryption(Images.java:310)
    at ciphers.Images.access$1(Images.java:286)
    at ciphers.Images$2.actionPerformed(Images.java:184)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:4
02)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)

我不知道我的代码有什么问题!在编写这段代码之前,我阅读了 SwingWorkerJProgressBar ,但我觉得我错过了一些东西!我能得到一个有用的提示吗.

I don't know what is wrong with my code! I read SwingWorker and JProgressBar before writing this code but I feel I'm missing something! Can I get a hint that helps.

谢谢:)

推荐答案

你似乎不明白 SwingWorker 的作用.

You seem to not understand what SwingWorker does.

SwingWorker 提供了一种方法,您可以通过该方法在事件调度线程的上下文之外执行长时间运行的任务.这意味着您的程序似乎不会被冻结.使用 SwingWorker(优于使用简单的 Thread)的好处是它提供了许多易于使用的方法来将更新重新同步回 EDT,缩进是为了阻止您破坏 Swing 的单线程规则:不应在除 EDT 之外的任何线程上创建或修改 UI 元素.

SwingWorker provides a means by which you can execute long running tasks outside the context of the Event Dispatching Thread. This means that your program won't appear to have become frozen. The benefit of using a SwingWorker (over using a simple Thread) is that it provides a number of easy to use methods to re-sync the updates back to the EDT, which is indented to stop you from breaking the single thread rules of Swing: No UI element should be created or modified on any thread other then the EDT.

仔细查看 工作线程和 SwingWorkerjavax.swing.SwingWorkerSwing 中的并发 了解更多详情

Tak a closer look at Worker Threads and SwingWorker and javax.swing.SwingWorker<T,V> and Concurrency in Swing for more details

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.event.IIOReadProgressListener;
import javax.imageio.event.IIOWriteProgressListener;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ConvertImage {

    public static void main(String[] args) {
        new ConvertImage();
    }

    public ConvertImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane tp = new TestPane();

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(tp);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                tp.convert(new File("C:\Users\Shane Whitehead\Dropbox\Wallpapers\animepaper.net_wallpaper_art_anime_aria_duanwu_festival_205050_wonderngo_7680x4800-a8aecc9c.jpg"));
            }
        });
    }

    public class TestPane extends JPanel implements ImageConverstionListener {

        private JLabel label = new JLabel("Waiting...");
        private JProgressBar pb = new JProgressBar();

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(label, gbc);
            add(pb, gbc);
        }

        public void convert(File file) {
            ConverterWorker worker = new ConverterWorker(file, this);
            worker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(final PropertyChangeEvent evt) {
                    if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
                        pb.setValue((int) evt.getNewValue());
                    }
                }
            });
            worker.execute();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        public void failedToConvertImage(File source, Throwable cause) {
            cause.printStackTrace();
            JOptionPane.showMessageDialog(this, "<html>Failed to convert " + source + "<br>" + cause.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }

        @Override
        public void imageConverted(File source, byte[] bytes) {
            JOptionPane.showMessageDialog(this, "Converted image to " + bytes.length + " bytes", "Converted", JOptionPane.INFORMATION_MESSAGE);
        }

        @Override
        public void setMessage(String msg) {
            label.setText(msg);
        }

    }

    public interface ImageConverstionListener {

        public void failedToConvertImage(File source, Throwable cause);

        public void imageConverted(File source, byte[] bytes);

        public void setMessage(String msg);

    }

    public class ConverterWorker extends SwingWorker<ByteArrayOutputStream, String> {

        private File source;
        private ImageConverstionListener listener;

        public ConverterWorker(File source, ImageConverstionListener listener) {
            this.source = source;
            this.listener = listener;
        }

        @Override
        protected void process(List<String> chunks) {
            listener.setMessage(chunks.get(chunks.size() - 1));
        }

        @Override
        protected ByteArrayOutputStream doInBackground() throws Exception {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            publish("Reading image...");
            try (ImageInputStream iis = ImageIO.createImageInputStream(source)) {
                Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
                if (readers.hasNext()) {
                    ImageReader reader = readers.next();
                    reader.addIIOReadProgressListener(new IIOReadProgressListener() {
                        @Override
                        public void sequenceStarted(ImageReader source, int minIndex) {
                        }

                        @Override
                        public void sequenceComplete(ImageReader source) {
                        }

                        @Override
                        public void imageStarted(ImageReader source, int imageIndex) {
                        }

                        @Override
                        public void imageProgress(ImageReader source, float percentageDone) {
                            setProgress(Math.round(percentageDone));
                        }

                        @Override
                        public void imageComplete(ImageReader source) {
                        }

                        @Override
                        public void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex) {
                        }

                        @Override
                        public void thumbnailProgress(ImageReader source, float percentageDone) {
                        }

                        @Override
                        public void thumbnailComplete(ImageReader source) {
                        }

                        @Override
                        public void readAborted(ImageReader source) {
                        }
                    });
                    reader.setInput(iis);
                    try {
                        BufferedImage img = reader.read(0);

                        publish("Converting image...");
                        try (ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) {
                            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("png");
                            if (writers.hasNext()) {
                                ImageWriter writer = writers.next();
                                writer.addIIOWriteProgressListener(new IIOWriteProgressListener() {
                                    @Override
                                    public void imageStarted(ImageWriter source, int imageIndex) {
                                    }

                                    @Override
                                    public void imageProgress(ImageWriter source, float percentageDone) {
                                        setProgress(Math.round(percentageDone));
                                    }

                                    @Override
                                    public void imageComplete(ImageWriter source) {
                                    }

                                    @Override
                                    public void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex) {
                                    }

                                    @Override
                                    public void thumbnailProgress(ImageWriter source, float percentageDone) {
                                    }

                                    @Override
                                    public void thumbnailComplete(ImageWriter source) {
                                    }

                                    @Override
                                    public void writeAborted(ImageWriter source) {
                                    }
                                });

                                writer.setOutput(ios);
                                try {
                                    writer.write(img);
                                } finally {
                                    writer.removeAllIIOWriteProgressListeners();
                                }
                            }
                        }
                    } finally {
                        reader.removeAllIIOReadProgressListeners();
                    }
                }
            }
            return baos;
        }

        @Override
        protected void done() {
            try {
                ByteArrayOutputStream baos = get();
                listener.imageConverted(source, baos.toByteArray());
            } catch (InterruptedException | ExecutionException ex) {
                listener.failedToConvertImage(source, ex);
            }
        }

    }

}

这篇关于SwingWorker 和 JProgressBar 的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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