Java 如何让类创建自己的图形实例

Java 如何让类创建自己的图形实例,java,class,graphics,paint,multiple-instances,Java,Class,Graphics,Paint,Multiple Instances,我有一个名为CharMove的类,其中有paint(Graphics g)方法和一些自定义方法。类应该创建一个正方形,然后在屏幕上随机移动该正方形。然而,当我在我的世界类中创建这个类的两个实例时,只有一个正方形出现。首先,方块不移动,但显示新坐标,然后运行5次后,方块开始随机移动。我认为该程序被图形方法所吸引,因为只有一个正方形被创建,而CharMove类应该创建另一个图形实例。我在网上搜索过,但找不到创建不同图形实例的方法。提前感谢 CharMove类 import java.awt.*; i

我有一个名为CharMove的类,其中有paint(Graphics g)方法和一些自定义方法。类应该创建一个正方形,然后在屏幕上随机移动该正方形。然而,当我在我的世界类中创建这个类的两个实例时,只有一个正方形出现。首先,方块不移动,但显示新坐标,然后运行5次后,方块开始随机移动。我认为该程序被图形方法所吸引,因为只有一个正方形被创建,而CharMove类应该创建另一个图形实例。我在网上搜索过,但找不到创建不同图形实例的方法。提前感谢

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

在swing中,所有的绘画都应该在paintComponent(图形g)中(重命名方法)

要制作动画,应使用Swing计时器(带ActionListener)更新动画项目的位置。完成后,计时器应调用repaint()

然而,当我在我的世界类中创建这个类的两个实例时,只有一个正方形出现

JFrame的默认布局管理器是BorderLayout

    game.add(char1);  
    game.add(char2);
如果在不指定约束的情况下添加零部件,则两个零部件都将添加到中心。但是,只能将一个零部件添加到中心,因此仅显示最后添加的零部件

尝试:

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

@Override
public Dimension getPreferredSize()
{
    return new Dimension(300, 200);
}
此外,自定义绘制应该在paintComponent(…)方法中完成,并且您需要在开始时调用super.paintComponent(…)以清除背景


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

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

要纠正这一点,您应该修改CharMove,以便它绘制所有的正方形(例如,通过维护一个数组或某种正方形集合,并在绘制方法中绘制所有正方形),然后只需将一个面板添加到JFrame


除此之外,当您在
移动
方法中设置正方形动画时,您正在阻止事件调度线程,这意味着在动画期间,您将无法移动任何其他窗口或响应任何鼠标单击或其他输入。接受ControlAltDel关于使用动画摆动计时器来纠正此问题的建议。

不是问题,而是
Graphics pane=(Graphics2D)g不是必需的:只需直接使用
g
。方法名称不应以大写字符开头。您是否见过以大写字符开头的“get”方法???遵循惯例。我可以复制并粘贴它吗?或者需要添加更多的语法吗?还有,这与我的移动方法有什么不同?谢谢你的建议。我喜欢你使用数组来计算对象的想法,看起来既有效又简单。还有,摆动计时器与我的移动方法有什么不同(它有什么不同之处)?
    game.add(char1);  
    game.add(char2);
    game.add(char1, BorderLayout.PAGE_START);  
    game.add(char2, BorderLayout.PAGE_END);
@Override
public Dimension getPreferredSize()
{
    return new Dimension(300, 200);
}