2011-10-22 67 views
-1

我正在嘗試做一個簡單的動畫,其中一個綠色的圓圈在一個名爲panel的小部件上以模糊的模式對角地移動,這是一個class MyPanel的實例,它擴展了JPanel如何讓綠色圓圈塗抹?

JFrame有一個啓動按鈕,按下該按鈕時應該通過調用actionPerformed方法(在我稱之爲動畫的方法,它調用repaint方法,同時相繼遞增圓的x和y座標啓動動畫)在本身就是監聽者的主類中。

取而代之的是,當按下按鈕時,圓圈出現在初始座標處,然後經過一段延遲後,另一個圓出現在最終座標處。有人能幫我弄清楚我哪裏出錯了嗎?我是Java的初學者,他在C年前完成了一些基本的編程。

在此先感謝。這裏是我的代碼:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class Smear implements ActionListener{ 
    JFrame frame; 
    MyPanel panel; 
    JButton button; 
    Smear animgui1; 
    int x=70; 
    int y=70; 

    public static void main(String[] args) { 
     Smear animgui=new Smear(); 
     animgui.project(); 
     animgui.set(animgui); 
    } 

    public void set(Smear anim) { 
     animgui1=anim; 
    } 

    public void project() { 
     frame=new JFrame(); 
     panel=new MyPanel(); 
     button=new JButton("Start"); 
     button.addActionListener(this); 
     frame.getContentPane().add(BorderLayout.NORTH, button); 
     frame.getContentPane().add(BorderLayout.CENTER, panel); 
     frame.setSize(300,300); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public void animate() { 
     while(x!=200) { 
      panel.repaint(); 
      x++; 
      y++; 
      System.out.println("++++"); 
      try { 
       Thread.sleep(50); 
      } 
      catch(Exception ex) {}; 
     } 
    } 

    public void actionPerformed(ActionEvent event) { 
     animgui1.animate(); 
    } 

    class MyPanel extends JPanel { 
     public void paintComponent(Graphics g) { 
      g.setColor(Color.green); 
      g.fillOval(x,y,40,40); 
     } 
    } 
} 

但在同一時間,我做了另一個程序SmearGui沒有該按鈕(我刪除有關按鈕和聽衆的代碼),和它的作品其意的方式;該圓圈緩慢移動塗抹模式。代碼爲:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class SmearGui{ 
    JFrame frame; 
    MyPanel panel; 
    //JButton button; 
    SmearGui animgui1; 
    int x=70; 
    int y=70; 

public static void main(String[] args){ 
     SmearGui animgui=new SmearGui(); 
     animgui.project(); 
     animgui.set(animgui); 
     animgui.animate(); 
} 
public void set(SmearGui anim){ 
     animgui1=anim; 
} 
public void project(){ 
     frame=new JFrame(); 
     panel=new MyPanel(); 
     //button=new JButton("Start"); 
     //button.addActionListener(this); 
     //frame.getContentPane().add(BorderLayout.NORTH, button); 
     frame.getContentPane().add(BorderLayout.CENTER, panel); 
     frame.setSize(300,300); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 
public void animate(){ 
    while(x!=200){ 
     panel.repaint(); 
     x++; 
     y++; 
     try{ 
     Thread.sleep(50); 
     } 
     catch(Exception ex){}; 
} 
} 
/*public void actionPerformed(ActionEvent event){ 
     animgui1.animate(); 
}*/ 
    class MyPanel extends JPanel{ 
     public void paintComponent(Graphics g){ 
     g.setColor(Color.green); 
     g.fillOval(x,y,40,40); 
} 
} 
} 

上面的代碼將animate方法放置在主體中。

+1

代碼縮進旨在幫助人們在閱讀代碼時瞭解代碼。你是否希望我們讀它? –

+1

'Thread.sleep(50);'不要那樣做。使用Swing ['Timer'](http://download.oracle.com/javase/7/docs/api/javax/swing/Timer.html)。 –

+0

哦..我很抱歉!將從現在開始照顧...並感謝!我剛開始學習java,大概有20-30天,而且我還沒有經歷過所有'〜Swing Timer的東西。 – stonecoldjha

回答

1

repaint是異步的,因此您的代碼不會等待面板重新繪製,然後才能繼續。你的循環代碼比重畫面板要快得多。使用一個擺動計時器,該計時器在重繪發生的同一個線程上執行,以便在計算與重繪時間中不會出現此不匹配。

+0

@ MeBigFatGuy請參考我編輯過的上述文章。我使用了Smear程序的全部代碼來創建另一個程序SmearGui,但不同之處在於我適當地註釋了/刪除了該按鈕及其偵聽器的代碼。而且,這個效果很好,因爲這個圓圈在面板對角線上沿着一個像運動一樣的拖影進行動畫。所以我猜,它必須與該按鈕有關。 – stonecoldjha

+0

@ user1008995這不是按鈕,事實上,在第二個版本中,動畫是在主線程中完成的,這也是執行繪製的線程。 – divegeek