当前位置: 首页 > 知识库问答 >
问题:

SwingWorker和JProgressBar的问题

羊舌成周
2023-03-14

我需要将给定的任何图像转换为字节数组,以满足加密要求。我正在使用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());

我定义了一个ProgressBar类,它使用SwingWorker,如下所示:

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个答案

桓瀚
2023-03-14

你似乎不明白SwingWorker做什么。

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

仔细看看Worker线程、SwingWorker和javax。摆动SwingWorker

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

    }

}

 类似资料:
  • 问题内容: 我有主GUI线程,其中有一个JprogressBar,并且正在实现ProprtyChangeListener。 当按下按钮时,扩展SwingWorker的其他类将开始执行并执行一系列可能很长的计算。我需要A类中的进度条以根据B类中的变量来呈现进度。 我的代码在下面(我所有失败的尝试都可能有点混乱…) 将不胜感激。 GUI类别: 计算类: 编辑 原始问题仍然存在。出于某种原因,进度条仍然

  • 介绍 (Introduction) JProgressBar类是一个可视地显示某个任务进度的组件。 Class 声明 (Class Declaration) 以下是javax.swing.JProgressBar类的声明 - public class JProgressBar extends JComponent implements SwingConstants, Access

  • 问题内容: 之间有什么区别? 和: 哪种方法更好用? 问题答案: 接受一个Runnable并在以后的ui线程中调用它。通常用于短期运行ui相关工作。 在非ui线程-工作线程中运行主要工作。完成长时间的工作后,将在ui线程(事件调度线程)中调用该方法。 但是,SwingWorker的方法也可以通过调用该方法来发布中间结果。这将确保要发布的结果由事件调度线程处理。您可以通过实现该方法进行连接。

  • 主要内容:1 Java JProgressBar的介绍,2 Java JProgressBar的声明,3 Java JProgressBar的构造方法,4 Java JProgressBar的方法,5 Java JProgressBar的案例1 Java JProgressBar的介绍 2 Java JProgressBar的声明 我们来看一下javax.swing.JProgressBar类的声明。 3 Java JProgressBar的构造方法 方法 描述 JProgressBar() 用

  • 问题内容: 我在FileReader上应用SwingWorker时遇到问题,我的观点是我需要在SwingWorker上实现FileReader,以使UI显示文件中的文本,这是我的代码 但是,它不会在UI文本区域上附加任何内容 有人有解决方案吗?谢谢 问题答案: 对我来说效果很好:

  • 问题内容: 我无法更新进度条…这是我的代码 进度栏状态仅在线程末尾更新。有人能帮我吗?? 问题答案: 谢谢大家 我这样解决了