Ein Fenster anhalten, bis es vollständig angezeigt wird?

Ich arbeite an einem Java-Programm, das eine große Anzahl von Dateien (maximal 3000) mit einem zugeordneten Array von 1/0-Dateien aufnimmt. Momentan habe ich eine Visualisierung des Arrays, wo es ein Gitter gibt, wo jede Box schwarz für 1 oder weiß für 0 gefüllt ist. Wenn sie gezeichnet wird, läuft sie gut, aber dauert etwa eine Minute, um den Computer vollständig zu laden (und möglicherweise den Computer in der Zwischenzeit). ) Gibt es einen Weg, ich kann: 1, das Fenster nicht anzeigen, bis es fertig ist

(dh JFrame erstellen,

// Fenster zeichnen

frame.setVisible (true))

und 2, verfolgen Sie den Fortschritt des processes, so dass ich einen Fortschrittsbalken damit verwenden kann?

edit: Kann ich einen Thread ausführen, um ihn zu zeichnen, und dann einfach eine while-Schleife erstellen, um ihn erst anzuzeigen, wenn der Thread fertig ist?

Im folgenden Beispiel setzt ein SwingWorker Pixel in einem BufferedImage basierend auf den Daten, die aus einer zufälligen Datei gelesen werden. Beachten Sie, dass Thread.sleep() verwendet wird, um Latenz zu simulieren; es ist sonst nicht erforderlich. Sie können eine JProgressBar wie hier gezeigt hinzufügen.

Gibt es einen besseren Weg, einfache farbige Boxen zu bekommen?

Ja. Im folgenden Beispiel repräsentiert jedes Pixel eine Zelle. Bei größeren Boxen geben Sie ein Vielfaches der Bildgröße zurück, z

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

Bild

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

Ich würde definitiv einen SwingWorker in diesem Fall verwenden. Grundsätzlich, vielleicht etwas in dieser Richtung (ich bin mir nicht sicher, welche Art von Objekt Ihre “Visualisierung” ist, also der Einfachheit halber sage ich nur, dass es ein Bild ist). Sie können dies am Ende Ihrer class hinzufügen. Sie müssen es natürlich bearbeiten, damit es für Sie funktioniert.

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

Um diese Methode aufzurufen, würden Sie (new DrawGridTask (objectToPutImageOn)) ausführen. Execute ();

Der gesamte Code in doInBackground () wird auf seinem eigenen Arbeitsthread ausgeführt. Done () wird im Ereignisversand-Thread ausgeführt und ruft die Referenz ab, die doInBackground () zurückgibt, wenn sie get () aufruft.

Hier finden Sie weitere Informationen dazu, wie Sie Fortschrittsaktualisierungen vornehmen können: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

Da ich Bilder erwähnt habe, wenn Sie mit ihnen arbeiten, möchten Sie vielleicht auch einen Blick auf die MediaTracker-class casting. Dies kann sehr nützlich sein, um zu blockieren, bis ein Bild fertig ist.