【问题标题】:How to draw an array of Graphics如何绘制图形数组
【发布时间】:2017-11-12 04:37:33
【问题描述】:

好的,所以我正在做一个学校项目(小动画),我目前正在尝试下雨。我不确定如何使用 JPanel 绘制单个“水滴”。到目前为止我的代码:

主类:

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

删除类:

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

我知道您现在是否会感到畏缩(我对图形编码还很陌生,而且对 Java 本身很熟悉)。我目前正在绘制的只是一个雨滴。任何建议表示赞赏。

【问题讨论】:

  • 你是说可能something like this example?
  • 不要从paint 内部调用super.paintComponent,覆盖paintComponent 代替
  • 你不应该在paint里面更新DropArray,这应该在其他地方完成,比如构造函数
  • 根据你的例子,Drop 不应该是一个组件
  • 如果我不应该使用Drop 作为组件,那应该是什么?顺便感谢您的回复。

标签: java swing graphics jpanel paintcomponent


【解决方案1】:
  • 不要从paint 内部调用super.paintComponent,你会破坏油漆链,这可能会导致无休止的问题。而是直接覆盖paintComponent
  • 您不应在任何绘制方法中修改组件的状态或组件所依赖的任何内容,绘制可以快速连续多次调用,这可能会导致无休止的问题
  • 基于组件的动画不是一项简单的任务,除非你真的非常需要它,否则你应该尽量避免它。相反,编写一个“可绘制”的类,您可以从您的 paintComponent 方法中调用它

例如..

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

    }

}

【讨论】:

  • 谢谢,我想我现在明白了。
猜你喜欢
  • 2018-01-06
  • 2021-11-25
  • 2016-08-12
  • 2021-03-03
  • 2021-10-24
  • 1970-01-01
  • 2014-12-19
  • 1970-01-01
相关资源
最近更新 更多