package edu.uwm.cs351; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JPanel; /** * A simulation of three particles in two dimensional Cartesian space * acting on each other using Newtonian gravitation. */ public class ParticleSimulation extends JPanel { /** * Put this in to keep Eclipse happy ("KEH"). */ private static final long serialVersionUID = 1L; private final ParticleSeq particles = new ParticleSeq(); /** * Create a particle simulation with three particles * @param p1 first particle, must not be null * @param p2 second particle, must not be null * @param p3 third particle, must not be null */ public ParticleSimulation(Particle p1, Particle p2, Particle p3) { if (p1 == null || p2 == null || p3 == null) { throw new NullPointerException("Cannot simulate with null particles"); } particles = new Particle[] {p1, p2, p3}; } // TODO: add the particles to the sequence @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // fetching a Graphics2D object from g // using a bit thicker pen // OLD code: //for (Particle p : particles) { //p.draw(g); //} // TODO: draw each particle } /** * Accelerate each particle by the gravitational force of each other particle. * Then compute the next position of all particles. */ public void move() { // OLD code: /* for (Particle p : particles) { Vector force = new Vector(); for (Particle other : particles) { if (other == p) continue; // no force from particle on itself force = force.add(other.gravForceOn(p)); } p.applyForce(force); } for (Particle p : particles) { p.move(); } */ // TODO: new code // Warning: Do not change "particles" in any way, // (e.g. don't call particles.start()) // because that could interfere with the paintComponent method repaint(); } }
Source code for DrawGraphics.java:
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
public class DrawGraphics
{
ArrayList<BouncingBox> boxes;
/** Initializes this class for drawing. */
public DrawGraphics()
{
boxes = new ArrayList<BouncingBox>();
boxes.add(new BouncingBox(200, 50, Color.GREEN));
boxes.get(0).setMovementVector(1,3);
boxes.add(new BouncingBox(100, 100, Color.BLUE));
boxes.get(1).setMovementVector(3,5);
boxes.add(new BouncingBox(50,50, Color.CYAN));
boxes.get(2).setMovementVector(6, 6);
}
/** Draw the contents of the window on surface. Called 20 times per second. */
public void draw(Graphics surface)
{
surface.drawLine(50, 50, 250, 250);
surface.drawOval(20, 20, 50, 50);
surface.drawRect(20, 100, 15, 60);
surface.drawArc(100, 30, 40, 40, 20, 30);
for(int i = 0; i < boxes.size(); i = i + 1)
{
boxes.get(i).draw(surface);
}
}
}
Source code for SimpleDraw.java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** Displays a window and delegates drawing to DrawGraphics. */
public class SimpleDraw extends JPanel implements Runnable {
private static final long serialVersionUID = -7469734580960165754L;
private boolean animate = true;
private final int FRAME_DELAY = 50; // 50 ms = 20 FPS
public static final int WIDTH = 300;
public static final int HEIGHT = 300;
private DrawGraphics draw;
public SimpleDraw(DrawGraphics drawer) {
this.draw = drawer;
}
/** Paint callback from Swing. Draw graphics using g. */
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Enable anti-aliasing for better looking graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
draw.draw(g2);
}
/** Enables periodic repaint calls. */
public synchronized void start() {
animate = true;
}
/** Pauses animation. */
public synchronized void stop() {
animate = false;
}
private synchronized boolean animationEnabled() {
return animate;
}
public void run() {
while (true) {
if (animationEnabled()) {
repaint();
}
try {
Thread.sleep(FRAME_DELAY);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String args[]) {
final SimpleDraw content = new SimpleDraw(new DrawGraphics());
JFrame frame = new JFrame("Graphics!");
Color bgColor = Color.white;
frame.setBackground(bgColor);
content.setBackground(bgColor);
// content.setSize(WIDTH, HEIGHT);
// content.setMinimumSize(new Dimension(WIDTH, HEIGHT));
content.setPreferredSize(new Dimension(WIDTH, HEIGHT));
// frame.setSize(WIDTH, HEIGHT);
frame.setContentPane(content);
frame.setResizable(false);
frame.pack();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) { System.exit(0); }
public void windowDeiconified(WindowEvent e) { content.start(); }
public void windowIconified(WindowEvent e) { content.stop(); }
});
new Thread(content).start();
frame.setVisible(true);
}
}
Source code for BouncingBox.java:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
public class BouncingBox {
int x;
int y;
Color color;
int xDirection = 0;
int yDirection = 0;
final int SIZE = 20;
/**
* Initialize a new box with its center located at (startX, startY), filled
* with startColor.
*/
public BouncingBox(int startX, int startY, Color startColor) {
x = startX;
y = startY;
color = startColor;
}
/** Draws the box at its current position on to surface. */
public void draw(Graphics surface) {
// Draw the object
surface.setColor(color);
surface.fillRect(x - SIZE/2, y - SIZE/2, SIZE, SIZE);
surface.setColor(Color.BLACK);
((Graphics2D) surface).setStroke(new BasicStroke(3.0f));
surface.drawRect(x - SIZE/2, y - SIZE/2, SIZE, SIZE);
// Move the center of the object each time we draw it
x += xDirection;
y += yDirection;
// If we have hit the edge and are moving in the wrong direction, reverse direction
// We check the direction because if a box is placed near the wall, we would get "stuck"
// rather than moving in the right direction
if ((x - SIZE/2 <= 0 && xDirection < 0) ||
(x + SIZE/2 >= SimpleDraw.WIDTH && xDirection > 0)) {
xDirection = -xDirection;
}
if ((y - SIZE/2 <= 0 && yDirection < 0) ||
(y + SIZE/2 >= SimpleDraw.HEIGHT && yDirection > 0)) {
yDirection = -yDirection;
}
}
public void setMovementVector(int xIncrement, int yIncrement) {
xDirection = xIncrement;
yDirection = yIncrement;
}
}
Trending now
This is a popular solution!
Step by step
Solved in 2 steps with 1 images