2013-07-24 39 views
-2

我想要以JFrame的形式加載圖像,使其看起來像是視頻。
更改圖像,如看起來像視頻

對於我以爲我會改變的圖像,以便更快(20張/秒)。

,但問題是,當新的圖像獲取加載其顯示全黑的窗口。
我不知道爲什麼會發生。
建議我在哪裏出錯了。

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Image; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import java.io.*; 
import javax.imageio.ImageIO; 

class VideoI extends JPanel { 

    private Image img; 
    private Graphics graphics; 
    ImageIcon icon; 

    VideoI(){ 
    icon=new ImageIcon("D:\\Videos\\1.jpg"); 
     add(icon); 
    } 

     public void paintComponent(Graphics g) { 
     graphics=g; 
     repeatImgs(); 
     } 

     public void repeatImgs(){ 
     for(int i=0;i<25;i++) 
     { try{ 
      img=ImageIO.read(new File("D:\\Videos\\"+i+".jpg")); 
      graphics.drawImage(img, 0, 0, null); 
      System.out.println(""+i); 
      Thread.sleep(1000); 
      }catch(Exception e){System.out.println(""+i+":"+e);} 
     } 


     } 

    } 

public class Video extends JFrame 
{ 
public static void main(String args[]) 
{ 
    new Video().start(); 
} 

public void start() 
{ 
    VideoI panel = new VideoI(); 

    add(panel); 

     setVisible(true); 

     setSize(1300,800); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

} 
    } 
+1

1)不要阻塞EDT(Event Dispatch Thread) - 當發生這種情況時GUI將「凍結」。而不是調用'Thread.sleep(n)'實現一個Swing'Timer'來重複執行任務,或者一個'SwingWorker'執行長時間運行的任務。有關更多詳細信息,請參見[Swing中的併發](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。 2)不要試圖加載循環中的圖像。 3)'graphics.drawImage(img,0,0,null);'應該是'graphics.drawImage(img,0,0,this);'4)對代碼塊使用一致的邏輯縮進。代碼的縮進旨在幫助人們理解流程。 –

+0

對不起,因爲我寫錯了代碼。
我沒有得到你的第二點。你能建議我可以做什麼,而不是使用for循環? –

+0

對點2的修復基本上是在構造函數中加載圖像,並簡單地將它們保存在數組或類似結構中。 –

回答

1

您正在阻止事件分派線程。使用揮杆Timer以所需的頻率重新繪製組件。

你永遠不應該在美國東部時間sleep()。你想要什麼本質上是

public void paintComponent(Graphics g) { 
    // No loops or delays, just fetch the next image, preferrably it has been 
    // already been loaded by another thread. 
    g.drawImage(getNextImage(), 0, 0, null); 
} 

和計時器任務:

ActionListener timerTask = new ActionListener() { 
    @Override 
    public void actionPerformed(final ActionEvent e) { 
     panel.repaint(); 
    } 
}; 

Timer timer = new Timer(50, timerTask); 

當你要開始視頻,只需調用timer.start()

最後,您還應該使用SwingUtilities.invokeLater()來包裝創建GUI。

+0

我應該在哪裏使用? (定時器計時器=新的計時器();)在主要方法或在我的JFrame .. &我需要添加ActionListernr ??? –

+0

「定時器」聲明可以轉到多個不同的地方,具體取決於應用程序的設計。例如,它可以是視頻類的一個領域。爲了快速測試,你可以把它放在你的'start()'方法中。 'ActionListener'是'Timer'每50ms執行一次的任務,不用擔心接口名稱。 – kiheru

+0

謝謝。它幫助我很多。我試試看,如果它不會工作,我會再次問你的幫助。 –

1

您正在發送事件調度線程(UI更新線程)進入睡眠狀態,這就是爲什麼您會遇到屏幕問題。 嘗試在工作線程中加載和切換圖像(查看JavaDoc的SwingWorker)。

1

我不是Swing的期待,但我想這會發生,因爲你停止與Thread.sleep Swing線程。您應該在擺動線外進行圖像更改和定時,並使用SwingUtilities.invokeLater來繪製圖像。你也需要睡50ms,而不是20fps的整秒。在這裏使用ScheduledExecutorService

此外,您總是從光盤加載圖像,當它需要被渲染。這可能會變慢。最好在啓動時加載所有圖像,然後更改圖像。

+0

謝謝。現在我得到一些擊球手的想法。但是,請你告訴我如何在啓動時加載所有圖像。我仍然認爲它會在我的應用程序上製造更多的burdon。不是嗎? –

+0

Just和另一個用於將所有圖像(1.jpg - 25.jpg)放入列表中的循環。顯示圖像時訪問列表。您將需要更多的內存,因爲圖像存儲在內存中。但是否則,圖像加載可能會減慢從光盤每秒鐘加載20個圖像。 – ssindelar

+0

我想它會使用很多內存(因爲我的所有圖像都是100kb的atlist)。 –