Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
205 views
in Technique[技术] by (71.8m points)

swing - Java - Random placement of objects

I'm working on a rain simulator. My idea is that every drop should be an object but for some reason they will not show up on the JFrame. If I change the values of the coordinates for the rectangle they appear but not if I randomize the numbers. What is causing the objects to not appear?

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class Rain extends RainDrop implements ActionListener{

    //Change the following 2 lines of variables to change the graphics
    static int width = 1000, height = 600;
    int dropAmount = 650, speed = 10;

    Timer tm = new Timer(speed, this);
    RainDrop[] RainDrop = new RainDrop[650];

    public Rain(){
        for(int i = 0; RainDrop.length > i; i++){
            RainDrop[i] = new RainDrop();
            RainDrop[i].generateRain();
            add(RainDrop[i]);
        }
        repaint();
    }

    public void paintComponent(Graphics g){
        tm.start();
    }

    public void actionPerformed(ActionEvent e){
        repaint();
    }

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setLocation(100, 100);
        f.setSize(width, height);
        f.setTitle("Rain");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Rain Rain = new Rain();
        f.add(Rain);
        f.setResizable(true);
        f.setVisible(true);
    }
    }

    import java.awt.Color;
    import java.awt.Graphics;
    import javax.swing.JPanel;

.

public class RainDrop extends JPanel{

//Drop [0] is used to store x values
//Drop [1] is used to store y values
//Drop [2] is used to store height values
//Drop [3] is used to store width values
//Drop [4] is used to store velocity values

private int[] Drop = new int [5];
private int width = 1000, height = 600;

public RainDrop(){
}

public int[] generateRain(){
        Drop [0] = (int) (Math.random() * width);       
        Drop [1] = (int) (Math.random() * height);
        Drop [2] = (int) (Math.random() * 13);
        Drop [3] = (int) (Math.random() * 4);
        Drop [4] = (int) (Math.random() * 6);

        if(Drop [2] < 5) Drop [2] += 9;

        if(Drop [3] < 3) Drop [3] += 3;

        if(Drop [3] == 5) Drop [3] = 4;

        if(Drop [4] < 3) Drop [4] += 3;

    return Drop;
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.red);

    g.fillRect(Drop [0], Drop [1], 5, 20);
}
}    
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The basic design is wrong. Rain should not extend RainDrop.

Rain should just be a JPanel with a paintComponent() method that paints a RainDrop object.

Create an ArrayList to hold RainDrop objects. Then you can start the Timer in the Rain panel. When the Timer fires you can iterate through all the RainDrop objects in the ArrayList and change the location of each RainDrop and then repaint() the panel.

Here is an example showing this basic approach. It show how to move balls around a panel:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class BallAnimation4
{
    private static void createAndShowUI()
    {
        BallPanel panel = new BallPanel();

        JFrame frame = new JFrame("BallAnimation4");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( panel );
        frame.setSize(800, 600);
        frame.setLocationRelativeTo( null );
        //frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setVisible( true );

        panel.addBalls(5);
        panel.startAnimation();
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

class BallPanel extends JPanel implements ActionListener
{
    private ArrayList<Ball> balls = new ArrayList<Ball>();

    public BallPanel()
    {
        setLayout( null );
        setBackground( Color.BLACK );
    }

    public void addBalls(int ballCount)
    {
        Random random = new Random();

        for (int i = 0; i < ballCount; i++)
        {
            Ball ball = new Ball();
            ball.setRandomColor(true);
            ball.setLocation(random.nextInt(getWidth()), random.nextInt(getHeight()));
            ball.setMoveRate(32, 32, 1, 1, true);
//          ball.setMoveRate(16, 16, 1, 1, true);
            ball.setSize(32, 32);
            balls.add( ball );
        }
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        for (Ball ball: balls)
        {
            ball.draw(g);
        }
    }

    public void startAnimation()
    {
        Timer timer = new Timer(75, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        move();
        repaint();
    }

    private void move()
    {
        for (Ball ball : balls)
        {
            ball.move(this);
        }
    }


    class Ball
    {
        public Color color = Color.BLACK;

        public int x = 0;
        public int y = 0;
        public int width  = 1;
        public int height = 1;

        private int moveX = 1;
        private int moveY = 1;
        private int directionX = 1;
        private int directionY = 1;
        private int xScale = moveX;
        private int yScale = moveY;

        private boolean randomMove = false;
        private boolean randomColor = false;
        private Random myRand = null;

        public Ball()
        {
            myRand = new Random();
            setRandomColor(randomColor);
        }

        public void move(JPanel parent)
        {
            int iRight = parent.getSize().width;
            int iBottom = parent.getSize().height;

            x += 5 + (xScale * directionX);
            y += 5 + (yScale * directionY);

            if (x <= 0)
            {
                x = 0;
                directionX *= (-1);
                xScale = randomMove ? myRand.nextInt(moveX) : moveX;
                if (randomColor) setRandomColor(randomColor);
            }

            if (x >= iRight - width)
            {
                x = iRight - width;
                directionX *= (-1);
                xScale = randomMove ? myRand.nextInt(moveX) : moveX;
                if (randomColor) setRandomColor(randomColor);
            }

            if (y <= 0)
            {
                y = 0;
                directionY *= (-1);
                yScale = randomMove ? myRand.nextInt(moveY) : moveY;
                if (randomColor) setRandomColor(randomColor);
            }

            if (y >= iBottom - height)
            {
                y = iBottom - height;
                directionY *= (-1);
                yScale = randomMove ? myRand.nextInt(moveY) : moveY;
                if (randomColor) setRandomColor(randomColor);
            }
        }

        public void draw(Graphics g)
        {
            g.setColor(color);
            g.fillOval(x, y, width, height);
        }

        public void setColor(Color c)
        {
            color = c;
        }

        public void setLocation(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove)
        {
            this.moveX = xMove;
            this.moveY = yMove;
            directionX  = xDir;
            directionY  = yDir;
            randomMove  = randMove;
        }

        public void setRandomColor(boolean randomColor)
        {
            this.randomColor = randomColor;

            switch (myRand.nextInt(3))
            {
                case 0:  color = Color.BLUE;
                         break;
                case 1:  color = Color.GREEN;
                         break;
                case 2:  color = Color.RED;
                         break;
                default: color = Color.BLACK;
                         break;
            }
        }

        public void setSize(int width, int height)
        {
            this.width  = width;
            this.height = height;
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...