2015-08-23 83 views
2

當我運行此代碼時,除了空白(白色)面板外,我什麼都看不到,我想知道爲什麼。爲什麼我的while循環在paintComponent中不起作用?

這裏是我的代碼:

Graph.java

public class Graph extends JPanel { 
    private static final long serialVersionUID = -397959590385297067L; 
    int screen=-1; 
    int x=10; 
    int y=10; 
    int dx=1; 
    int dy=1;  
    boolean shouldrun=true; 
    imageStream imget=new imageStream(); 

     protected void Loader(Graphics g){ 

      g.setColor(Color.black); 
      g.fillRect(0,0,x,y); 
      x=x+1; 
      y=y+2; 

     } 


     @Override 
     protected void paintComponent(Graphics g){ 
      super.paintComponent(g); 
       while(shouldrun){ 
        Loader(g); 
        try { 
         Thread.sleep(200); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        }  
       } 
     } 
} 
+0

看一看[Swing中的併發(http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)和[如何使用Swing定時器(http://docs.oracle.com /javase/tutorial/uiswing/misc/timer.html) – MadProgrammer

回答

10

永遠不要叫Thread.sleep()Event Dispatch Thread

這會導致實際重畫屏幕並使控件響應停止執行的線程任何東西

For animations, use a Timer。不要擔心自己寫while循環,只要告知Timer每隔一段時間就會觸發一次,並在該定時器內更改xy的值。喜歡的東西:

// this is an **inner** class of Graph 
public class TimerActionListener implements ActionListener { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     x += dx; 
     y += dy; 
    } 
} 

// snip 
private final Timer yourTimer; 

public Graph() { 
    yourTimer = new Timer(2000, new TimerActionListener()); 
    timer.start(); 
} 
所有的
@Override 
protected void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    g.setColor(Color.black); 
    g.fillRect(0,0,x,y); 
} 
+0

是啊,他說什麼! 1+ –

+0

它不是一個動畫壽,這個想法是在遊戲中有一個水平,一個加載屏幕和一個菜單。我想要一個循環來重新運行圖形取決於整數屏幕。 –

+1

@DanjahSoftProgrammer事件調度線程會自動爲您執行循環的工作。 **你不需要擔心重複繪製它,因爲Swing對你來說就像魔術一樣!**這段代碼與你提供的代碼很相似,你在你的'Loader'方法中調用'x = x + 1',這是做同樣的事情,除了'Timer'而不是while循環。 – durron597

4

你永遠不會改變shouldrun州內環路 - 所以它永遠不會結束。

而且,從來沒有一幅畫方法中調用Thread.sleep(...)。這種方法是用於繪畫的,永遠不能入睡,否則GUI將被放入睡眠狀態,將被凍結。

+0

噢,我明白了。是的,它永遠不會結束。但我應該如何使它迭代?在主代碼中重繪?...忽略此 –

0

首先,你的paintComponent方法應該只處理所有的畫,沒有別的(如果可能)。你不應該在paintComponent中實現你的程序循環。

空白屏幕可能由多種原因引起。您可以通過評論代碼的某些部分並運行它來手動輕鬆地進行調試。看看它是否仍然是空白的。

至少從我在這裏看到的,你的paintComponent會給你的問題。

如果你想要一個動畫,您可以:

  1. 使用擺動計時器

  2. 創建一個新的線程(不是事件指派線程)的循環。你的循環將是這個樣子:

如下:

while(running){ 
    update(); 
    render(); 
    try(
     Thread.sleep(1000/fps); 
    )catch(InterruptedException ie){ 
     ie.printStackTrace(); 
    } 
} 

注:爲了使動畫適當的循環,你將需要不止於此。

+0

」它應該只是繪畫,否則代碼中存在某些重大缺陷。 – Emz

+0

@ durron597看看大學給出的這個樣本嗎? http://www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html – user3437460

+0

@ durron597最簡單的方法就是使用計時器,但是如果程序/遊戲變得複雜,那將會更好創建一個Thread並在該線程中運行遊戲循環,而不是在EDT中做所有事情,不是嗎?所以從這個角度來看,並不是絕對的,Java動畫必須只用揮杆定時器來完成。 – user3437460

相關問題