Stopping a window from displaying till it is fully drawn?

In the example below, a SwingWorker sets pixels in a BufferedImage based on the data read from a random file. Note that Thread.sleep() is used to simulate latency; it is otherwise not required. You can add a JProgressBar as shown here.

Is there a better way to get simple colored boxes?

Yes. In the example below, each pixel represents one cell. For larger boxes, return a multiple of the image size, e.g.

@Override
public Dimension getPreferredSize() {
    return new Dimension(2 * N, 2 * N);
}

image

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;

/**
 * @see https://stackoverflow.com/a/25043676/230513
 */
public class WorkerTest {

    private static final int N = 256;
    private final BooleanPanel panel = new BooleanPanel();

    private class BooleanPanel extends JPanel {

        private BufferedImage image;

        public void setImage(BufferedImage bi) {
            this.image = bi;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.drawImage(image, 0, 0, getWidth(), getHeight(), null);
        }

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

    private class BufferedImageWorker extends SwingWorker<BufferedImage, BufferedImage> {

        @Override
        protected BufferedImage doInBackground() throws Exception {
            BufferedImage image = new BufferedImage(N, N, BufferedImage.TYPE_INT_ARGB);
            try (DataInputStream dis = new DataInputStream(
                    new BufferedInputStream(new FileInputStream("/dev/random")))) {
                for (int row = 0; row < N; row++) {
                    for (int col = 0; col < N; col++) {
                        image.setRGB(col, row, dis.readByte() < 0 ? 0xffffffff : 0xff000000);
                    }
                    Thread.sleep(40); // ~25 Hz
                    publish(image);
                }
                return image;
            }
        }

        @Override
        protected void process(List<BufferedImage> list) {
            for (BufferedImage bi : list) {
                panel.setImage(bi);
                panel.repaint();
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("WorkerTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(panel);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        new BufferedImageWorker().execute();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new WorkerTest().display();
        });
    }
}

Leave a Comment