2011-01-03 16 views
2

Hey, also arbeite ich an einem Programm und zu Debugging-Zwecken, ich versuche, das Programm einen Screenshot von einem Teil des Displays zu machen. Ich möchte die Anzeige aktualisiert haben, aber ich kann es nicht funktionieren lassen. Ich bin mir sicher, dass es ein einfaches Problem ist, aber meine Erfahrung mit Java Applets ist sehr klein.Kann JFrame nicht zum Aktualisieren des Bildes

Hier ist der Teil, den ich habe Probleme mit:

... 
Thread.sleep(5000); 
    try {gb = new GameBoard(frame.getBounds());} 
    catch(Exception e){System.out.println("Error.");} // Make "gameboard" Object 

    while (true) 
    { 
     Thread.sleep(1000); 
     gb.grabImage(); // use java.awt.Robot's createScreenCapture() 

     ImageIcon icon = new ImageIcon(gb.image()); // wrap the image 
     JLabel label = new JLabel(icon, JLabel.CENTER); 
     frame.getContentPane().add(label,BorderLayout.EAST); //display the image (works) 
     //JOptionPane.showMessageDialog(null, label, "icon", -1); 
     label.repaint(); //update the display?? 
     frame.repaint(); 
     frame.getContentPane().repaint(); 
    } 

Wie gesagt, wird das Bild, und neue schaffen, wenn ich die Applet Größe zu ändern, aber ich brauche ein ständig wechselndes Bild.

Vielen Dank im Voraus!

+1

Sind Sie sicher, dass dies ein Applet und keine Anwendung ist? Ich glaube, dass Standardeinstellungen die Erstellung von java.awt.Robot in einem Applet verbieten. –

+1

Versuchen Sie, dies zu tun ... 'label.revalidate(); label.repaint(); '. – Favonius

Antwort

5

Sie erstellen und fügen ein neues JLabel jedes Mal durch die Schleife. Da Sie die Struktur der Komponentenstruktur ändern, müssen Sie revalidate im Inhaltsbereich des Frames aufrufen.

Eine bessere Lösung wäre, nur das Bild auf einem einzelnen JLabel zu ändern. Erstellen Sie ein Label, fügen Sie es hinzu, und verwenden Sie dann in Ihrer Schleife JLabel.setIcon und repaint.

+1

Übrigens sollten Sie sich darüber informieren, wie Sie Swing mit Threads verwenden - Sie sollten alle GUI-Änderungen am Event-Versand-Thread vornehmen, indem Sie 'SwingUtilities.invokeLater' und' SwingUtilities.invokeAndwait' verwenden. Swing-Komponenten sind nicht threadsicher, daher kann das Ändern der Komponentenstruktur oder das Aufrufen von Setter-Komponenten in Swing-Komponenten unsicher sein, wenn sie von anderen Threads aus ausgeführt werden. –

2

Wie @RD Notizen, createScreenCapture() wird eine SecurityException werfen, wenn das Applet nicht signiert ist. Das Schlafen im Ereignisversand-Thread blockiert möglicherweise Aktualisierungen. Diese example erfasst ein Bildschirmbild beim Ziehen der Maus; sein BufferedImage "merkt" sich das zuletzt aufgenommene Bild.

+1

Kleinigkeit: Das Applet wird eine SecurityException auslösen, wenn es nicht vertrauenswürdig ist. Dies erfordert, dass beide signiert werden, und wenn der Zeitpunkt gekommen ist, kann der Benutzer den signierten Code akzeptieren und entscheidet sich dafür. Dies ist ein subtiler, aber wichtiger Unterschied, da der JCP beispielsweise so konfiguriert werden kann, dass Benutzer Code akzeptieren können, der von einem verifizierten Sicherheitszertifikat signiert wurde, jedoch nicht, wenn es nur vom Entwickler erstellt wurde. –

+0

@Andrew Thompson: Danke für die Erweiterung auf diese! – trashgod

0

Von dem, was ich mich erinnere, repaint() in Java sollte eigentlich invalidate() genannt werden - es repaint tatsächlich nicht das Fenster; es macht es nur ungültig, so dass es bei der nächsten Gelegenheit vom Betriebssystem neu gezeichnet werden kann. Ich habe mir Ihren Code nicht genau angesehen, aber ich denke, das könnte das Problem sein. Ich bin nicht sicher, wie man ein Neuzeichnen erzwingt, aber eine Idee wäre, von der Funktion zurückzukehren, dann einen Timer zu unterbrechen und es dann zu malen - auf diese Weise wird das OS eine Chance haben, das Fenster zu malen.

+1

Nicht ganz. 'Repaint' markiert die Komponente als zu bemalend; 'invalidate' markiert die Komponente so, als müsste das Layout neu berechnet werden. Es gibt eine "repaintImmediately" -Methode, wenn Sie wirklich wollen, dass sie jetzt neu streicht, aber Sie wollen das nicht verwenden, solange Sie sich nicht absolut sicher sind, was Sie tun. –

+0

Ich wusste nicht, dass es eine "invalidate" -Methode in Java gab - ich meinte "invalidate" wie in Windows (wie 'InvalidateRect()') und das .NET Framework (wie 'Control.Invalidate()'), denn das bezieht sich auf Malerei und nicht auf Layout. Danke, dass du es aufgezeigt hast, Entschuldigung für die Verwirrung. – Mehrdad