如何让一个类创建自己的Graphics实例

时间:2015-10-18 21:58:31

标签: java class graphics paint multiple-instances

我有一个名为CharMove的类,它有paint(Graphics g)方法和一些自定义方法。该类应创建一个正方形,然后在屏幕上随机移动该正方形。但是,当我在World Class中创建此类的两个实例时,只显示一个方块。首先,正方形不会移动,但显示新的坐标。然后在5次运行后,正方形开始随机移动。我认为该程序正在陷入Graphics方法,因为只有一个正方形正在创建,当CharMove类应该创建另一个Graphics.I实例已在线搜索但无法找到创建不同Graphics.Thanks实例的方法。提前。

CharMove Class

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);
    } 
}

3 个答案:

答案 0 :(得分:1)

在摇摆中,你的所有绘画都应该在paintComponent(Graphics g)中重命名(重命名你的方法)

要进行动画制作,您应该使用Swing Timer(带有ActionListener)来更新动画项目的位置。一旦完成,计时器应该调用repaint();

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

}

答案 1 :(得分:1)

  

但是,当我在World Class中创建此类的两个实例时,只会出现一个方块。

JFrame的默认布局管理器是BorderLayout。

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

在未指定约束的情况下添加组件时,两个组件都将添加到CENTER中。但是,只有一个组件可以添加到CENTER中,因此只显示添加的最后一个组件。

尝试:

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

但是,当您执行此操作时,将不会显示组件,因为它们具有(0,0)preferredSize。因此,您还需要覆盖CharMove类的getPreferredSize()方法。

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

此外,自定义绘制应在paintComponent(...)方法中完成,您需要在开始时调用super.paintComponent(...)以清除背景。

move()方法中的repaint()方法应该在面板上,而不是框架上,因为您正在更改面板的属性。

答案 2 :(得分:0)

每个CharMove基本上都是JPanel,在绘制时会在其自身的某处绘制一个大小为10的正方形。您正在向CharMove JFrame添加两个game面板(实际上将它们添加到默认内容窗格,其中有一个子类BorderLayout)。由于您没有提供布局约束对象,实际上两个面板都被添加到内容窗格的BorderLayout.CENTER,第二个面板完全覆盖了第一个。

要纠正这个问题,你应该修改CharMove,使它绘制所有正方形(例如,通过维护一个数组或某种方形的集合,并在paint方法中绘制所有这些正方形),然后将一个面板添加到的JFrame。

除了这个问题,当您在movement方法中设置正方形时,您正在阻止事件调度线程,这意味着在动画期间您无法移动任何其他窗口或响应任何鼠标点击或其他输入。请参阅ControlAltDel关于使用Swing Timer进行动画修正此问题的建议。