SwingWorker和JProgressBar问题
我需要将给定的任何图像转换为字节数组以满足encryption要求。 我使用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());
我定义了一个使用SwingWorker
的ProgressBar
类,如下所示:
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)
我不知道我的代码有什么问题! 在编写这段代码之前,我读了SwingWorker
和JProgressBar
,但是我觉得我错过了一些东西! 我能得到一个有帮助的提示吗?
谢谢 :)
你似乎不明白什么SwingWorker
。
SwingWorker
提供了一种方法,您可以在事件派发线程的上下文之外执行长时间运行的任务。 这意味着你的程序似乎不会被冻结。 使用SwingWorker
(通过使用简单的Thread
)的好处是它提供了许多简单易用的方法将更新重新同步到EDT,缩进以避免打破Swing的单线程规则:在EDT之外的任何线程上都不应该创build或修改UI元素。
详细了解Worker Threads和SwingWorker以及javax.swing.SwingWorker<T,V>
和Swing中的并发性
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); } } } }