2012-06-17 113 views
1

我無法越過此JPanel移動此JLabel?我把下面的代碼。基本上應該發生的是,JLabel所謂的「傢伙」慢慢地向右移動。唯一的問題是,JLabel不會刷新它,在我第一次移動它之後就會消失。刷新JPanel中移動的JLabel

public class Window extends JFrame{ 

    JPanel panel = new JPanel(); 
    JLabel guy = new JLabel(new ImageIcon("guy.gif")); 
    int counterVariable = 1; 

    //Just the constructor that is called once to set up a frame. 
    Window(){ 
     super("ThisIsAWindow"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     add(panel); 
     panel.setLayout(null); 
    } 

    //This method is called once and has a while loop to exectue what is inside. 
    //This is also where "counterVariable" starts at zero, then gradually 
    //goes up. The variable that goes up is suposed to move the JLabel "guy"... 
    public void drawWorld(){ 
     while(true){ 
      guy.setBounds(counterVariable,0,50,50); 
      panel.add(guy); 
      counterVarialbe++; 
      setVisible(true); 
      try{Thread.sleep(100)}catch(Exception e){} 
     } 

    } 

任何想法,爲什麼將JLabel剛剛消失,而不是移動到右側後,我改變變量「counterVariable」。 - 謝謝! :)

+1

你從監聽器裏或在組件的調用從事件指派線程(例如,這種方法繪製方法或...)? – Untitled

+0

在我去的主要方法中,Window gui = new Window();然後> gui.drawWorld(); yup ... –

回答

4

您的代碼導致長時間運行過程中對Swing事件線程這是防止這種線程做必要的操作上運行:油漆GUI和響應用戶的輸入。這將有效地讓你的整個GUI進入睡眠狀態。

問題&建議:

  • 決不呼籲Swing事件分派線程或EDT Thread.sleep(...)
  • 從來沒有在一個EDT while (true)
  • 而是用於所有的這一個Swing Timer
  • 無需繼續將JLabel添加到JPanel。一旦添加到JPanel中,它仍然存在。
  • 同樣,沒有必要繼續呼籲JLabel的setVisible(true)。一旦可見,它仍然可見。
  • 呼叫repaint()粉盒保持在移動的JLabel上已經移至後,請求將容器及其子女被重新繪製。

例如,

public void drawWorld(){ 
    guy.setBounds(counterVariable,0,50,50); 
    int timerDelay = 100; 
    new javax.swing.Timer(timerDelay, new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
     countVariable++; 
     guy.setBounds(counterVariable,0,50,50); 
     panel.repaint(); 
    } 
    }).start; 
} 

警告:代碼無法編譯,運行或測試的任何方式

+0

我以前從來沒有見過這種方法(我還沒有編程這麼長時間),但是panel.repaint()會做什麼? –

+0

@BenHagel:'repaint()'方法在事件線程上排隊請求,讓組件調用方法重新繪製。這是必需的,因爲當您移動JPanel所持有的JLabel時,您所做的更改將僅在包含標籤的JPanel被重新繪製時纔會顯示。請注意,調用'repaint()'不能保證組件被繪製,而是一個強大的請求,因爲如果很多重繪被疊加起來,有些將被忽略。請閱讀[在AWT和Swing中繪畫](http://java.sun.com/products/jfc/tsc/articles/painting/)以瞭解所有這些細節。 –

+0

謝謝,我明白現在好多了!我會爲你的答案投票! 順便說一句:好用戶名XD –