2015-10-18 73 views
0

我有一個名爲CharMove的類,它是paint(Graphics g)方法和一些自定義方法。班級應創建一個正方形,然後在屏幕上隨機移動該正方形。但是,當我在我的世界級中創建這個類的兩個實例時,只會出現一個方塊。首先廣場不移動,但顯示新的座標。然後5次運行後,廣場開始隨機移動。我認爲該程序被捕獲的Graphics方法,因爲只有一個正方形正在創建,當CharMove類應該創建Graphics.I的另一個實例已經在網上搜索,但無法找到一種方法來創建Graphics.Thanks的不同實例提前。如何讓一個類創建自己的Graphics實例

CharMove類

import java.awt.*; 
import java.util.concurrent.TimeUnit; 
import javax.swing.*; 
import java.util.Random; 

public class CharMove extends JPanel { 
    int x = 250; 
    int y = 250; 
    public void paint(Graphics g) { 
     Graphics pane = (Graphics2D) g; 
     pane.setColor(Color.blue); 
     pane.fillRect(x, y, 10, 10); 

    } 

    public void movement(JFrame frame) { 
     for (int i=0;i<5;i++) { 
      try { 
       TimeUnit.SECONDS.sleep(1); 
       this.x = Getx(this.x,frame); 
       this.y = Gety(this.y,frame); 
       frame.repaint(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public int Getx(int a, JFrame frame) { 
     Random rn = new Random(); 
     int xnum = rn.nextInt(10)-5; 
     a += xnum; 
     System.out.println("x:" + a); 
     return a; 
    } 
    public int Gety(int b, JFrame frame){ 
     Random rn = new Random(); 
     int ynum = rn.nextInt(10)-5; 
     b += ynum; 
     System.out.println("y:" + b); 
     return b; 
    } 
} 

世界級

import java.awt.*; 
import java.util.concurrent.TimeUnit; 
import javax.swing.*; 
import java.util.Random; 
public class World { 


    public static void main(String[] args) { 

     JFrame game = new JFrame(); 
     game.setTitle("Matrix"); 
     game.setSize(500, 500);; 
     game.getContentPane().setBackground(Color.white); 
     game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     game.setVisible(true); 
     CharMove char1 = new CharMove(); 
     CharMove char2 = new CharMove(); 
     game.add(char1); 
     game.add(char2); 
     char1.movement(game); 
     char2.movement(game); 
    } 
} 
+0

不是問題,但'Graphics pane =(Graphics2D)g;'不是必須的:只需直接使用'g'。 –

+0

方法名稱不應以大寫字符開頭。你有沒有見過以大寫字母開頭的「get」方法?遵循約定。 – camickr

回答

0

每個CharMove本質上是一個JPanel,當它被繪時,它自己的某個地方繪製一個10的單個正方形。您正在將兩個CharMove面板添加到game JFrame(實際上將它們添加到默認內容窗格,其具有子類型BorderLayout)。由於您不提供佈局約束對象,實際上這兩個面板都將添加到內容窗格的BorderLayout.CENTER,而第二個面板完全覆蓋第一個面板。

爲了糾正這個問題,你應該修改CharMove,以便它繪製所有的方塊(例如,通過維護一個數組或某些方塊集合,並在paint方法中繪製所有的方塊),然後只添加一個面板到JFrame。

除了這個問題,當您在動畫movement方法中的方塊時,您將阻止事件調度線程,這意味着在動畫期間,您將無法移動任何其他窗口或響應任何鼠標點擊或響應其他投入。採取ControlAltDel關於使用Swing Timer進行動畫的建議來糾正此問題。

+0

感謝您的建議。我喜歡使用數組來計算對象的想法,看起來有效且容易。另外,Swing Timer與我的移動方法有什麼不同(它與它的不同之處是什麼)? – Ninjaman494

1

在擺動,所有你的畫應該​​是向下的paintComponent(圖形G)(重命名方法)

做動畫,您應該使用Swing Timer(帶有ActionListener)來更新動畫項目的位置。一旦完成,定時器應該調用repaint();

public void actionPerformed(ActionEvent ae) { 
    this.x = Getx(this.x,frame); 
    this.y = Gety(this.y,frame); 
    frame.repaint(); 

} 
+0

我可以直接複製並粘貼它嗎?還是需要添加更多語法?這與我的移動方法有什麼不同? – Ninjaman494

1

然而,當我在我的世界級創建該類的兩個實例,只出現一個正方形。

JFrame的默認佈局管理器是一個BorderLayout。

game.add(char1); 
    game.add(char2); 

當您添加組件時未指定約束,則將這兩個組件添加到CENTER中。但是,只有一個組件可以添加到CENTER中,因此只顯示最後添加的組件。

嘗試:

game.add(char1, BorderLayout.PAGE_START); 
    game.add(char2, BorderLayout.PAGE_END); 

然而,當你這樣做的componens將不會顯示,因爲他們有一個(0,0)首選大小。所以你也需要重寫你的CharMove類的getPreferredSize()方法。

@Override 
public Dimension getPreferredSize() 
{ 
    return new Dimension(300, 200); 
} 

此外,風俗畫應在的paintComponent(...)方法做,你需要在開始時要調用super.paintComponent方法(...),以清除背景。

您的move()方法中的repaint()方法應位於面板上,而不是框架上,因爲您正在更改面板的屬性。

相關問題