/*
* Open Source Physics software is free software as described near the bottom of this code file.
*
* For additional information and documentation on Open Source Physics please see:
* <http://www.opensourcephysics.org/>
*/
package org.opensourcephysics.frames;
import java.awt.Graphics;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Iterator;
import org.opensourcephysics.display.DisplayColors;
import org.opensourcephysics.display.Drawable;
import org.opensourcephysics.display.DrawingFrame;
import org.opensourcephysics.display.DrawingPanel;
import org.opensourcephysics.display.Interactive;
import org.opensourcephysics.display.InteractiveCircle;
import org.opensourcephysics.display.Measurable;
import org.opensourcephysics.display.PlottingPanel;
/**
* A DrawingFrame that displays particles.
*
* Particle locations are specified using a Point2D.
* The default particle drawing shape is a circle.
*
* @author W. Christian
* @version 1.0
*/
public class ParticleFrame extends DrawingFrame {
ArrayList<Particles> partlist = new ArrayList<Particles>();
/**
* Constructs the ParticleFrame with the given labels and frame title.
*
* @param xlabel String
* @param ylabel String
* @param frameTitle String
*/
public ParticleFrame(String xlabel, String ylabel, String frameTitle) {
super(new PlottingPanel(xlabel, ylabel, null));
setTitle(frameTitle);
setAnimated(true);
setAutoclear(true);
}
/**
* Ensures capacity
*
* @param index
*/
protected Particles checkIndex(int index) {
while(index>=partlist.size()) {
Particles p = new Particles();
partlist.add(p);
((InteractiveCircle) p.shape).color = DisplayColors.getLineColor(partlist.indexOf(p));
addDrawable(p);
}
return partlist.get(index);
}
/**
* Adds a particle to the frame.
*
* @param i
* @param point
*/
public void addParticle(int i, Point2D point) {
checkIndex(i).addParticle(point);
}
/**
* Adds an array of particles to the frame.
*
* @param i
* @param points
*/
public void addParicle(int i, Point2D[] points) {
checkIndex(i).addParticles(points);
}
/**
* Sets the drawing shape for the particles.
*
* @param i
* @param shape Interactive
*/
public void setDrawingShape(int i, Interactive shape) {
checkIndex(i).shape = shape;
}
/**
* Cleares drawable objects added by the user from this frame and clears the particles.
*/
public void clearDrawables() {
clearData();
drawingPanel.clear(); // removes drawables added by user
}
/**
* Clears all particles from this frame.
*/
public void clearData() {
Iterator<Particles> it = partlist.iterator();
while(it.hasNext()) { // clears the data from the arrays
Particles p = it.next();
(p).clear();
drawingPanel.removeDrawable(p);
}
partlist.clear();
drawingPanel.invalidateImage();
}
class Particles implements Drawable, Measurable {
Interactive shape = new InteractiveCircle();
private ArrayList<Point2D> pointList = new ArrayList<Point2D>();
double xmin = Double.MAX_VALUE, xmax = -Double.MAX_VALUE, ymin = Double.MAX_VALUE, ymax = -Double.MAX_VALUE;
Particles() {
shape.setEnabled(false); // default cannot drag particles
}
void addParticle(Point2D point) {
synchronized(pointList) {
xmax = Math.max(xmax, point.getX());
xmin = Math.min(xmin, point.getX());
ymax = Math.max(ymax, point.getY());
ymin = Math.min(ymin, point.getY());
pointList.add(point);
}
}
void addParticles(Point2D[] points) {
if(points==null) {
return;
}
for(int i = 0, n = points.length; i<n; i++) {
xmax = Math.max(xmax, points[i].getX());
xmin = Math.min(xmin, points[i].getX());
ymax = Math.max(ymax, points[i].getY());
ymin = Math.min(ymin, points[i].getY());
}
synchronized(pointList) {
for(int i = 0, n = points.length; i<n; i++) {
pointList.add(points[i]);
}
}
}
void clear() {
synchronized(pointList) {
pointList.clear();
xmin = Double.MAX_VALUE;
xmax = -Double.MAX_VALUE;
ymin = Double.MAX_VALUE;
ymax = -Double.MAX_VALUE;
}
}
/**
* Draws the particles.
*
* @param panel DrawingPanel
* @param g Graphics
*/
public void draw(DrawingPanel panel, Graphics g) {
synchronized(pointList) {
Iterator<Point2D> it = pointList.iterator();
while(it.hasNext()) {
Point2D point = (it.next());
shape.setXY(point.getX(), point.getY());
shape.draw(panel, g);
}
}
}
/**
* getXMax
*
* @return double
*/
public double getXMax() {
return xmax;
}
/**
* getXMin
*
* @return double
*/
public double getXMin() {
return xmin;
}
/**
* getYMax
*
* @return double
*/
public double getYMax() {
return ymax;
}
/**
* getYMin
*
* @return double
*/
public double getYMin() {
return ymin;
}
/**
* There is a measure if there is at least one particle.
*
* @return boolean
*/
public boolean isMeasured() {
synchronized(pointList) {
return(pointList.size()>0) ? true : false;
}
}
}
}
/*
* Open Source Physics software is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public License (GPL) as
* published by the Free Software Foundation; either version 2 of the License,
* or(at your option) any later version.
* Code that uses any portion of the code in the org.opensourcephysics package
* or any subpackage (subdirectory) of this package must must also be be released
* under the GNU GPL license.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
* or view the license online at http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2007 The Open Source Physics project
* http://www.opensourcephysics.org
*/