简体   繁体   English

如何绘制图形数组

[英]How to draw an array of Graphics

OK so i'm working on a school project (little animation) and I am currently trying to make rain. 好,所以我正在做一个学校项目(小动画),而我目前正想下雨。 I'm not sure how I would go about drawing individual "drops" using JPanel. 我不确定如何使用JPanel绘制单个“滴”。 My Code so far: 到目前为止,我的代码:

Main Class: 主类:

public class RainPanel extends JPanel {
private static final long serialVersionUID = 1L;

public static void main(String[] args) {
    new RainPanel();
}
private final int WIDTH = 800, HEIGHT = 800;

Drop drop;

public RainPanel() {
    init();
}

public void init() {
    JFrame frame = new JFrame("Rain");
    JPanel drop = new Drop();
    frame.setVisible(true);
    frame.setSize(WIDTH, HEIGHT);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.add(drop);
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
        drop.paint(g);
}

Drop class: 掉落类:

public class Drop extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;

int x,y;
int yVel = 2;

Timer t = new Timer(5, this);
Random r = new Random();
ArrayList<Drop> DropArray;

public Drop() {
    x = r.nextInt(800);
    y = r.nextInt(800);
    t.start();
}

public void paint(Graphics g) {
    super.paintComponent(g);
    DropArray = new ArrayList<>(100); 
    for (int i = 0; i < DropArray.size(); i++) {
        DropArray.add(new Drop());
    }
    g.setColor(Color.BLUE);
    g.fillRect(x, y, 3, 15);
}

public void update() {
    y += yVel;
    if (y > 800) 
        y = r.nextInt(800);
}

@Override
public void actionPerformed(ActionEvent e) {
        update();
        repaint();
}

I understand if you might be cringing hard right now (I'm fairly new to graphics coding and mostly familiar with Java itself). 我知道您现在是否可能会努力奋斗(我对图形编码是相当陌生的,并且大多数人对Java本身很熟悉)。 All i'm getting drawn currently is a single rain drop. 目前我所吸引的只是一滴雨。 Any suggestions are appreciated. 任何建议表示赞赏。

  • Don't call super.paintComponent from within paint , you're breaking the paint chain which could cause no end of issues. 不要在paint内部调用super.paintComponent ,否则会破坏绘画链,这可能不会导致任何问题。 Override paintComponent directly instead 直接改写paintComponent
  • You shouldn't be modifying the state of a component or anything the component relies on from within any paint method, paint can be called a number of times in quick succession and this can cause no end of issues 您不应该在任何绘制方法中修改组件的状态或组件所依赖的任何内容,可以快速连续多次调用绘制,这不会导致任何问题
  • Component based animation is not a simple task and unless you really, really need it, you should try and avoid it. 基于组件的动画绝非易事,除非您真的非常需要它,否则应避免使用它。 Instead, write a class which is "paintable", which you can call from your paintComponent method 而是编写一个“可绘画”的类,您可以从paintComponent方法中调用该类

For example.. 例如..

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class RainDropsKeepFalling {

    public static void main(String[] args) {
        new RainDropsKeepFalling();
    }

    public RainDropsKeepFalling() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new RainPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class RainPane extends JPanel {

        private List<Drop> drops = new ArrayList<>(100);

        public RainPane() {
            for (int index = 0; index < 100; index++) {
                drops.add(new Drop(getPreferredSize()));
            }

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    for (Drop drop : drops) {
                        drop.update(getSize());
                        repaint();
                    }
                }
            });
            timer.start();
        }

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

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            for (Drop drop : drops) {
                Graphics2D g2d = (Graphics2D) g.create();
                drop.paint(g2d);
                g2d.dispose();
            }
        }

    }

    protected static final Random random = new Random();

    public static class Drop {

        private double vDelta = random.nextDouble() + 0.5;
        private int height = 15;
        private int width = 3;
        private double x;
        private double y = -height;

        private Rectangle2D shape;

        public Drop(Dimension size) {
            x = random.nextInt(size.width - width) + width;
            y = random.nextInt(size.height - height) + height;
            shape = new Rectangle2D.Double(x, y, width, height);
        }

        public void paint(Graphics2D g2d) {
            g2d.setColor(Color.BLUE);
            g2d.fill(shape);
        }

        public void update(Dimension size) {
            y += vDelta;
            if (y > size.height) {
                y = -height;
                x = random.nextInt(size.width - width) + width;
            }
            shape.setRect(x, y, width, height);
        }

    }

}

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

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