Randomly Generating a shape

2019-06-05 11:05发布

I am working on a Java screen saver project and so far I have a good portion done. I need the code to generate a random shape of random color in a random position. I believe I have all of the random aspects taken care of, but now I just need to use a timer to create these shapes at 500 ms intervals. I also need to create a counter to count 30 shapes and then clear the screen and start again. (I have the background and the keylistener added for other parts of the project, but they are working perfect, in case anyone was wondering why they were there).

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

public class ScreenSaver1 extends JPanel implements ActionListener {
    private JFrame frame = new JFrame("FullSize");
    private Rectangle rectangle;
    Timer t;
    int x1, y1;
    boolean full;

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        int shape;
        shape = (int)(Math.random() * 4);
    }

    ScreenSaver1() {
        t = new Timer(500, this);
        t.setDelay(500);
        t.start();
        // Remove the title bar, min, max, close stuff
        frame.setUndecorated(true);
        // Add a Key Listener to the frame
        frame.addKeyListener(new KeyHandler());
        // Add this panel object to the frame
        frame.add(this);
        // Get the dimensions of the screen
        rectangle = GraphicsEnvironment.getLocalGraphicsEnvironment()
        .getDefaultScreenDevice().getDefaultConfiguration().getBounds();
        // Set the size of the frame to the size of the screen
        frame.setSize(rectangle.width, rectangle.height);
        frame.setVisible(true);
        // Remember that we are currently at full size
        full = true;
    }


// This method will run when any key is pressed in the window
class KeyHandler extends KeyAdapter {
    public void keyPressed(KeyEvent e) {
        // Terminate the program.
        if (e.getKeyChar() == 'x') {
            System.out.println("Exiting");
            System.exit(0);
        }
        else if (e.getKeyChar() == 'r') {
            System.out.println("Change background color");
            setBackground(new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256)));
            repaint();
        }
        else if (e.getKeyChar() == 'z') {
            System.out.println("Resizing");
            frame.setSize((int)rectangle.getWidth() / 2, (int)rectangle.getHeight());
        }
    }

}

private void makeLine(Graphics g) {
    int x = (int)(Math.random() * rectangle.getWidth());
    int y = (int)(Math.random() * rectangle.getHeight());
    int x1 = (int)(Math.random() * 100);
    int y1 = (int)(Math.random() * 100);
    g.setColor(new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256) ));
    g.drawLine(x, y, x1, y1);
}

private void makeRect(Graphics g) {
    int x = (int)(Math.random() * rectangle.getWidth());
    int y = (int)(Math.random() * rectangle.getHeight());
    int width = (int)(Math.random() * 100);
    int height = (int)(Math.random() * 100);
    g.setColor(new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256) ));
    g.drawRect(x, y, width, height);
}

private void makeOval(Graphics g) {
    int x = (int)(Math.random() * rectangle.getWidth());
    int y = (int)(Math.random() * rectangle.getHeight());
    int width = (int)(Math.random() * 100);
    int height = (int)(Math.random() * 100);
    g.setColor(new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256) ));
    g.drawOval(x, y, width, height);
}

private void makeRoundRect(Graphics g) {
    int x = (int)(Math.random() * rectangle.getWidth());
    int y = (int)(Math.random() * rectangle.getHeight());
    int width = (int)(Math.random() * 100);
    int height = (int)(Math.random() * 100);
    int arcWidth = (int)(Math.random() * width);
    int arcHeight = (int)(Math.random() * height);
    g.setColor(new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256) ));
    g.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
}

public static void main(String[] args) {
        ScreenSaver1 obj = new ScreenSaver1();
    }
}

标签: java timer count
3条回答
我只想做你的唯一
2楼-- · 2019-06-05 11:31

Check out Playing With Shapes for an approach that allows you to use Shapes as a real component. Then you just add the component to a panel and you don't have to worry about custom painting.

查看更多
Explosion°爆炸
3楼-- · 2019-06-05 11:37

You're not going to like me, but I would suggest that you back up slightly...

To start with, Java provides a really good basic Shape interface, which defines how a "shape" should be rendered (amongst other things), so rather the completely reinventing the wheel, I would suggest you start with this.

Next, you need some kind of object that wraps both the Shape (which has position and size information) and the Color, for example...

public class RandomShape {

    private final Color color;
    private final Shape shape;

    public RandomShape(Color color, Shape shape) {
        this.color = color;
        this.shape = shape;
    }

    public Color getColor() {
        return color;
    }

    public Shape getShape() {
        return shape;
    }

    public void paint(Graphics2D g2d) {
        g2d.setColor(color);
        g2d.draw(shape);
        g2d.fill(shape);
    }

}

This even has the ability to paint itself.

Next, I would create a List to contain these shapes...

private List<RandomShape> shapes;

This not only acts as your counter, but makes it incredibly simple to update the screen. When the shapes List contains 30 or more items, you simply clear it and repaint the screen...

Next, you need a javax.swing.Timer, which is used to trigger the updates...

This timer should...

Check to see if the shapes list needs to be cleared...

Randomly generate the Color...

int r = (int) (Math.random() * 255);
int g = (int) (Math.random() * 255);
int b = (int) (Math.random() * 255);
Color color = new Color(r, g, b);

Randomly generate the size and position of the shape...

int width = 10 + (int) (Math.random() * 40);
int height = 10 + (int) (Math.random() * 40);
int x = (int) (Math.random() * (getWidth() - width));
int y = (int) (Math.random() * (getHeight() - height));

Randomly generate the underlying basic shape...

Shape shape = null;
switch (whichShape) {
    case 0:
        shape = new Line2D.Double(x, y, x + width, y + height);
        break;
    case 1:
        shape = new Rectangle2D.Double(x, y, width, height);
        break;
    case 2:
        shape = new Ellipse2D.Double(x, y, width, height);
        break;
}

Create the RandomShape, add it to the list and repaint the component...

RandomShape randomShape = new RandomShape(color, shape);
shapes.add(randomShape);
repaint();

Simple ;)

Now, when you need to paint the component, you simply iterate over the list of shapes...

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g.create();
    for (RandomShape shape : shapes) {
        shape.paint(g2d);
    }
    g2d.dispose();
}

Take a look at How to use Swing Timers and Working with Geometry

查看更多
一纸荒年 Trace。
4楼-- · 2019-06-05 11:37

You can paint all shapes without using a loop like this

private void paintAllShapes(Graphics g, int n) {
    if(n < shapes.size()) {
        shapes.get(n).paint((Graphics2D)g);
        paintAllShapes(g, n+1);
    }
}

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    paintAllShapes(g, 0);
}
查看更多
登录 后发表回答