阻止窗口显示直到完全绘制?

我正在开发一个Java程序,它接收大量文件(最多3000个)和一个相关的1/0数组。 目前我有一个数组的可视化,其中有一个网格,其中每个框填充为黑色为1或白色为0.当绘制它运行良好但需要大约一分钟才能完全加载(并且可能在此期间锁定计算机。 )有没有办法:1,在完成之前不要显示窗口

(即JFrame创建,

//画窗口

frame.setVisible(真))

和2,跟踪进程的进度,以便我可以使用进度条吗?

编辑:我可以运行一个线程来绘制它,然后简单地创建一个while循环只在线程完成后显示它吗?

在下面的示例中, SwingWorker根据从随机文件中读取的数据设置BufferedImage的像素。 请注意, Thread.sleep()用于模拟延迟; 否则不需要。 您可以添加JProgressBar ,如下所示。

有没有更好的方法来获得简单的彩色盒子?

是。 在下面的示例中,每个像素代表一个单元格。 对于较大的盒子,返回图像大小的倍数,例如

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

图片

 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 { @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 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(); }); } } 

在这种情况下,我肯定会使用SwingWorker。 基本上,也许是沿着这些方向的东西(我不确定你的’可视化’是什么类型的对象,所以为了简单起见,我只是说它是一个图像)。 您可以在课程的底部添加它。 你显然必须编辑它以使它适合你。

 protected class DrawGridTask extends SwingWorker { ObjectToPutImageOn imageObject; public DrawGridTask(ObjectToPutImageOn obj) { this.imageObject = obj; } protected Image doInBackground() { // generate your Image or graphic or whatever here return Image; } protected void done() { imageObject.drawThisCompletedImage(get()); } } 

要调用此方法,您将运行(new DrawGridTask(objectToPutImageOn))。execute();

doInBackground()中的所有代码都将在它自己的工作线程上运行。 Done()在事件调度线程上运行,并在调用get()时获取引用doInBackground()返回。

这里有更多信息,包括如何进行更新: http : //docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

由于我提到了Images,如果你使用它们,你可能还想看看MediaTracker类,这对于阻塞非常有用,直到图像准备好。