有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

SwingWorker和JProgressBar的java问题

我需要将给定的任何图像转换为字节数组以满足加密要求。我正在使用JProgressBar监控所选图像较大时的转换进度:

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());

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

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
               }
        }
}

不幸的是,这个错误发生了

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,但我觉得我遗漏了一些东西!我能得到一个有用的提示吗

谢谢:)


共 (1) 个答案

  1. # 1 楼答案

    你似乎不明白SwingWorker做什么

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

    请仔细查看Worker Threads and SwingWorker^{}Concurrency in Swing了解更多详细信息

    Convert

    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);
                }
            }
    
        }
    
    }