2015-10-18 74 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()方法应位于面板上,而不是框架上,因为您正在更改面板的属性。

相关问题