简体   繁体   English

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

[英]How to have a class create its own instance of Graphics

I have a class called CharMove,in it are the paint(Graphics g) method, and some custom methods. 我有一个称为CharMove的类,其中有paint(Graphics g)方法和一些自定义方法。 The class should create a square,then move that square randomly around the screen. 班级应创建一个正方形,然后在屏幕上随机移动该正方形。 However,when I create two instances of this class in my World Class,only one square appears. 但是,当我在World Class中创建该类的两个实例时,只会出现一个正方形。 First the square doesn't move but the new coord.'s are displayed,then after 5 runs the square begins to move randomly. 首先正方形不移动,但显示新坐标。然后运行5次后,正方形开始随机移动。 I think the program is getting caught on the Graphics method because only one square is being created,when the CharMove class should be creating another instance of Graphics.I have searched online but can't find a way to create different instances of Graphics.Thanks in advance. 我认为程序正在使用Graphics方法,因为当CharMove类应该创建另一个Graphics实例时,仅创建一个正方形。我在网上搜索但找不到找到创建Graphics实例的方法。提前。

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

World Class 世界级

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

In swing, all of your painting should be down in paintComponent(Graphics g) (rename your method) 摆动时,所有绘画都应放在paintComponent(Graphics g)中(重命名方法)

To do animation, you should use a Swing Timer (w/ an ActionListener) to update the positions of your animated items. 要制作动画,您应该使用Swing计时器(带有ActionListener)来更新动画项目的位置。 Once that's done, the timer should call repaint(); 完成后,计时器应调用repaint();。

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

}

However,when I create two instances of this class in my World Class,only one square appears. 但是,当我在World Class中创建该类的两个实例时,只会出现一个正方形。

The default layout manager for a JFrame is a BorderLayout. JFrame的默认布局管理器是BorderLayout。

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

When you add components without specifying a constraint then both components are added to the CENTER. 当您添加组件而未指定约束时,两个组件都将添加到CENTER。 However, only one component can be added to the CENTER so only the last one added is displayed. 但是,只能将一个组件添加到CENTER,因此仅显示最后一个添加的组件。

Try: 尝试:

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

However when you do this the componens won't be displayed because they have a (0, 0) preferredSize. 但是,当您执行此操作时,组件将不会显示,因为它们具有(0,0)preferredSize。 So you will also need to override the getPreferredSize() method of your CharMove class. 因此,您还需要重写CharMove类的getPreferredSize()方法。

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

Also, custom painting should be done in the paintComponent(...) method and you need to invoke super.paintComponent(...) at the start to clear the background. 另外,自定义绘画应在paintComponent(...)方法中完成,并且您需要在开始时调用super.paintComponent(...)以清除背景。

The repaint() method in your movement() method should be on the panel, not the frame, since you are changing properties of the panel. 由于您要更改面板的属性,所以Movement()方法中的repaint()方法应该位于面板上,而不是框架上。

Each CharMove is essentially a JPanel which draws a single square of size 10 somewhere on itself when it is painted. 每个CharMove本质上都是一个JPanel ,在绘制时会在其某处绘制一个大小为10的单个正方形。 You are adding two CharMove panels to the game JFrame (which in fact adds them to the default content pane, which has a subclassed BorderLayout ). 您正在向game JFrame中添加两个CharMove面板(实际上是将它们添加到具有子类BorderLayout的默认内容窗格中)。 As you are not providing a layout constraints object, in fact both panels are being added to the BorderLayout.CENTER of the content pane, and the second is completely covering the first. 由于您没有提供布局约束对象,因此实际上两个面板都已添加到内容窗格的BorderLayout.CENTER中,而第二个面板则完全覆盖了第一个面板。

To correct this you should modify CharMove so that it paints all of the squares (eg by maintaining an array or some sort of collection of squares, and painting all of them in the paint method) and just add that one panel to the JFrame. 要纠正此问题,您应该修改CharMove,使其绘制所有正方形(例如,通过维护数组或某种正方形集合,并在paint方法中绘制所有正方形),然后仅将一个面板添加到JFrame中。

Apart from this issue, while you are animating the squares in the movement method you are blocking the Event Dispatch Thread, meaning that during the animation you won't be able to move any other windows or respond to any mouse clicks or other inputs. 除了这个问题之外,当您在movement方法中对正方形进行动画处理时,您将阻塞事件分发线程,这意味着在动画期间您将无法移动任何其他窗口或响应任何鼠标单击或其他输入。 Take ControlAltDel's advice about using the Swing Timer for animation to correct this problem. 采取ControlAltDel的有关使用Swing Timer进行动画处理的建议来纠正此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM