| Test Program | Simulation interface | ControlFrame | ControlMenu |
| Table | Plot | WorldGraphics | SimFormat |
The simphy package is designed to implement some basic tasks that are useful in many simulations of physical systems. Objects can be created from the classes in this package without knowing the details of how the classes are written. However, we also list the classes below for interested users who may wish to modify or extend them. Any class that uses the simphy package must include the statement import simphy.*; at the beginning of the file containing the class. In the following we list the classes and describe what they do and how they can be used. If you are using Metrowerks CodeWarrior then the simphy package jar file must be added to your project.
ControlFrame
String Blist[] = {"start", "stop", "reset"};
String Llist[] = {"Temperature", "Lattice Size"};
double Tlist[] = {2.2,64};
ControlFrame cf = new ControlFrame(S, Llist, Tlist, Blist);
This example creates three buttons and two TextFields with Labels below them. When a button is
pressed or a TextField changed, another object needs to know. To accomplish this communication, the
object S must implement the interface Simulation. Why do we use an interface? Why not
just write a class with the necessary methods? The answer is that the interface lets ControlFrame
have an instantiation of any class as an argument as long as that class
implements the Simulation interface. Any class that implements Simulation must
include the methods shown in the following example.
public class Example implements Simulation
{
public void buttonAction(int k)
{
// respond to Buttons numbered from 0 to number of Buttons - 1
}
public void textAction(int k, double x)
{
// respond to TextFields numbered from 0 to number of TextFields - 1
}
public void menuAction(int k)
{
// respond to Menus that perform actions numbered from 0 to number of Menu items - 1
}
public void dialogAction(int k, double x)
{
// respond to Menus that call up dialog boxes numbered from 0 to number of Menu items - 1
}
}
This interface is used with ControlMenu also. In method textAction and
dialogAction, the double x is the value entered into a TextField by the user.
ControlMenu
This class has the same functionality as ControlFrame. Two Menus
are created, one called "Actions" and one called "Parameters" which play the same role as the
Buttons and TextFields, respectively. The constructor for ControlMenu works in the same way as
the constructor for ControlFrame. Before using the ControlMenu you must first attach
the menubar to a frame:
fr.setMenuBar(cm.sBar); // fr = Frame object , cm = ControlMenu object
Table
This class displays a table of formated numbers separated by tabs in a Frame. The
constructor arguments are the TableName and a String array of table headings for the columns. The
class contains methods for setting formats for the entries to the table, adding entries to a row (one at
a time or up to the first 5 entries at once), and displaying a row. The Table can be copied from the
Frame and pasted directly into a spreadsheet or plotting program. Below we show an example.
"String h[] = {"Column A","Column B","Column C"};
Table tb = new Table("Example Table",h);
String pattern[] = {"#.0000", "#.00","#.000"};
tb.setFormat(pattern,10); // width of each column is 10 characters
tb.setEntry(0,3.173); // set zeroth element of row
tb.setEntry(1,999.9173); // set first element of row
tb.setEntry(2,3891.73); // set second element of row
tb.displayEntries(); // display first row
tb.setEntries(3317.3,99.173,817.3); // set all three elements of row at once
tb.displayEntries(); // display second row
The result of the above code is to produce a table that looks like the following:
Column A Column B Column C
3.1730 999.91 3891.730
3317.3000 99.17 817.300
In some cases you may wish to show the entire table all at once to avoid flicker as each
row is shown. To do this use the constructor
Table(String TableName, String h[],int FieldSize, boolean visibility) with visibility
set equal to false. When all the entries to the table have been displayed, then call
showTable() to see the table on the screen.
Plot
public Plot(String title, String xLabel, String yLabel, int nAxes,
double xmin,double xmax, double ymin, double ymax, int symbolSize, String symbolType
int xsize, int ysize, int xloc, int yloc)
/* nAxes = 1, one bottom horizontal axis, ymin should = 0
nAxes = 2, one left vertical axis, one bottom horizontal axis, xmin and ymin should = 0
nAxes = 3, one center vertical axis, one bottom horizontal axis, xmin should = -xmax, ymin should = 0
nAxes = 4, crossed axes, xmin should = -xmax and ymin should = -ymax
nAxes = 5, crossed axes, only x > 0, xmin should = 0 and ymin should = -ymax
nAxes = anything else, no axes drawn.
symbolType = "fillsquare" or "opensquare" or "opencircle" or "fillcircle"
symbolSize = 1 for point (default), otherwise gives size in pixels
*/
public void plotPoints(double x[], double y[]);
public void plotPoint(double x, double y); // Plot one point
public void plotCurve(double x[], double y[]);
public void clear(); // clears frame on buffer
public void clearPoints(); // clears frame and replots axes
public void setColor(String s);
WorldGraphics
public WorldGraphics(String title,
double xmin,double xmax, double ymin, double ymax, int size, int xLoc, int yLoc)
The offscreen buffer can be used to do animation and speed up graphics. To do this call the method setToScreen(false), which will cause all subsequent drawing methods to draw only to the offscreen buffer and not to the screen. Then to draw the buffer to the screen, call drawBuffer(). Animation can be achieved for an image moving from one place to another by clearing the old location of the image using clearRect(x,y,dx,dy), drawing the image at the new location, and then calling drawBuffer().
SimFormat
SimFormat.dformat(33.12765,3); // returns 33.127
SimFormat.eformat(-0.00364); // returns -3.640 E-3
SimFormat.aformat(-3078.6,2,1.0,10.0); // returns -3.07 E3
SimFormat.aformat(-3078.6); // returns -3.078 E3
// default values are min = 0.001, max = 100, d = 3
Test Program
A test program showing how these classes are instantiated and used is shown below. Try running this program and testing the Buttons, TextFields, and menu items. Find the code in the program for the things you see on the screen.
import simphy.*;
public class Test implements Simulation
{
ControlFrame cf;
ControlMenu cm ;
WorldGraphics wg;
public static void main(String args[])
{
Test u = new Test();
}
public Test()
{
String h[] = {"zero","first","second"};
Table tb = new Table("test",h);
String pattern[] = {"#.0000", "#.00","#.000"};
tb.setFormat(pattern,10);
tb.setEntry(0,3.173);
tb.setEntry(1,999.9173);
tb.setEntry(2,3891.73);
tb.displayEntries();
tb.setEntries(3317.3,99.173,817.3);
tb.displayEntries();
String lString[] = {"zero", "one", "two","three", "four", "five","six", "seven", "eight"};
String bString[] = {"A", "B", "C","D", "E", "F","G", "H", "I"};
double initialP[] = { 1,2,3,4,5,6,7,8,9};
ControlFrame cf = new ControlFrame(this,lString,initialP,bString);
ControlMenu cm = new ControlMenu(this,lString,initialP,bString);
WorldGraphics wg = new WorldGraphics("Visualization",0,10,0,10, 500, 200,200);
wg.setMenuBar(cm.sBar);
}
public void buttonAction(int k)
{
double x[] = {0,1,2,3,4};
double y[] = {0,1,2,3,4};
switch(k)
{
case 0: Plot p = new Plot("y vs x","xxxx","yyyy",1,-5,5,0,5);p.plotPoints(x,y);break;
case 1: Plot p1 = new Plot("y vs x","xxxx","yyyy",2,-5,5,0,5);p1.plotPoints(x,y);break;
case 2: Plot p2 = new Plot("y vs x","xxxx","yyyy",3,-5,5,0,5);p2.plotPoints(x,y);break;
case 3: Plot p3 = new Plot("y vs x","xxxx","yyyy",4,-5,5,0,5);p3.plotPoints(x,y);break;
}
}
public void textAction(int k, double x)
{
System.out.println(x);
cf.setText(0,x);
cf.setText(1,(int) x);
cf.setText(2,"hello " + String.valueOf(k));
}
public void menuAction(int k)
{
switch(k)
{
case 0: wg.drawRect(5,5,4,4.0); break;
case 1: wg.drawString("good job", 7.0,2.0);break;
case 2: wg.drawLine(0,0,10,10);break;
case 3: wg.drawRect(200,200,100,100);break;
case 4: wg.drawCircle(5,5,3);break;
case 5: wg.clearRect(0,0,10,10);break;
case 6: wg.setColor("yellow");break;
case 7: wg.setColor("green");break;
case 8: wg.setColor("random");break;
}
cf.texts[1].setText(String.valueOf(k)); // shows which menu selected in a TextField
}
public void dialogAction(int k, double x)
{
System.out.println(x);
}
}
package simphy;
public interface Simulation
{ // used with ControlFrame or ControlMenu
public void buttonAction(int k);
public void textAction(int k, double x);
public void menuAction(int k);
public void dialogAction(int k, double x);
}
ControlFrame
package simphy;
import java.awt.*;
import java.awt.event.*;
public class ControlFrame extends Frame
{
public TextField texts[];
Label labels[];
Button buttons[];
Simulation S;
String lString[], bString[];
double x[];
public ControlFrame(Simulation S, String lString[], String bString[])
{
this.S = S;
this.lString = lString;
this.bString = bString;
int nT = lString.length;
x = new double[nT];
for(int i = 0; i < nT;i++)
x[i] = 0.0;
setUpFrame();
}
public ControlFrame(Simulation S, String lString[], double x[], String bString[])
{
this.S = S;
this.lString = lString;
this.bString = bString;
this.x = x;
setUpFrame();
}
public void setUpFrame()
{
int ix = 20, iy = 20,bxT = 100,by = 20, ysep = 80, lsep = 20;
int fSize = 0, bx;
int nT = lString.length; // number of textfields
int nB = bString.length; // number of buttons
for (int i = 0; i < nB; i++)
fSize += 20 + max(bString[i].length()*10,bxT);
for (int i = 0; i < nT; i++)
fSize += 20 + max(lString[i].length()*10,bxT);
if(fSize < 500)
setSize(fSize, ysep);
else
{
setSize(500, (2 + fSize/500)*ysep);
fSize = 500;
}
setTitle("Controls");
this.S = S;
setLayout(null);
texts = new TextField[nT]; // new array of textfields
labels = new Label[nT]; // new array of labels
buttons = new Button[nB]; // new array of buttons
for(int i = 0; i < nB;i++)
{
bx = max(bString[i].length()*10,bxT); // button size
if(ix + bx + 20 > fSize)
{
ix = 20;
iy += ysep;
}
buttons[i] = new Button(bString[i]); // new button
buttons[i].addActionListener(new B(i)); // add listener
buttons[i].setSize(bx,by);
buttons[i].setLocation(ix,iy);
add(buttons[i]); // add button
ix += bx + 20;
}
for(int i = 0; i < nT;i++)
{
bx = max(lString[i].length()*10,bxT); // label size
if(ix + bx + 20 > fSize)
{
ix = 20;
iy += ysep;
}
labels[i]= new Label(lString[i]); // new label for textfield
labels[i].setSize(bx,by);
labels[i].setLocation(ix,iy+lsep);
add(labels[i]); // add label
if( (int) x[i] == x[i])
texts[i]= new TextField(String.valueOf( (int) x[i])); // new textfield
else
texts[i]= new TextField(String.valueOf(x[i])); // new textfield
texts[i].addActionListener( new T(i)); // add listener
texts[i].setSize(bxT,by);
texts[i].setLocation(ix,iy);
add(texts[i]); // add textfield
ix += bx + 20;
}
setVisible(true);
}
private int max(int a, int b)
{
if ( a > b)
return a;
else
return b;
}
public void setText(int k, String s)
{
texts[k].setText(s);
}
public void setText(int k, int x)
{
texts[k].setText(String.valueOf(x));
}
public void setText(int k, double x)
{
texts[k].setText(String.valueOf(x));
}
// Inner classes
class B implements ActionListener
{
int k; // kth button
public B(int k)
{
this.k = k;
}
public void actionPerformed(ActionEvent e)
{
S.buttonAction(k);
}
}
class T implements ActionListener
{
int k; // kth TextField
public T(int k)
{
this.k = k;
}
public void actionPerformed(ActionEvent e)
{
Double R = new Double(texts[k].getText().trim());
S.textAction(k,R.doubleValue());
}
}
}
ControlMenu
package simphy;
import java.awt.*;
import java.awt.event.*;
public class ControlMenu
{
public MenuBar sBar; // declare menubar
Menu bMenu,tMenu; // declare two menus
MenuItem bItems[]; // declare array of menu items
MenuItem tItems[]; // declare array of menu items
Simulation S;
String lString[], bString[];
public double x[];
public ControlMenu(Simulation S, String lString[], String bString[])
{
this.S = S;
this.lString = lString;
this.bString = bString;
int nT = lString.length;
x = new double[nT];
for(int i = 0; i < nT;i++)
x[i] = 0.0;
setUpMenu();
}
public ControlMenu(Simulation S, String lString[], double x[], String bString[])
{
this.S = S;
this.lString = lString;
this.bString = bString;
this.x = x;
setUpMenu();
}
public void setUpMenu()
{
sBar = new MenuBar(); // assign menubar
bMenu = new Menu("Actions"); // assign menu
tMenu = new Menu("Parameters"); // assign menu
sBar.add(bMenu); // add menu to menubar
sBar.add(tMenu); // add menu to menubar
int nB = bString.length;
bItems = new MenuItem[nB]; // assign array of menu items
int nT = lString.length;
tItems = new MenuItem[nT]; // assign array of menu items
for(int i = 0; i < nT;i++)
{
tItems[i] = new MenuItem(lString[i]); // assign menu item to array element
tItems[i].addActionListener( new T(i));
tMenu.add(tItems[i]); } // add menu item to menu
for(int i = 0; i < nB;i++)
{
bItems[i] = new MenuItem(bString[i]); // assign menu item to array element
bItems[i].addActionListener( new B(i));
bMenu.add(bItems[i]); // add menu item to menu
}
}
class B implements ActionListener
{
int k;
public B(int k)
{
this.k = k;
}
public void actionPerformed(ActionEvent e)
{
S.menuAction(k);
}
}
class T implements ActionListener
{
int k;
public T(int k)
{
this.k = k;
}
public void actionPerformed(ActionEvent e)
{
InputDialog d = new InputDialog(S,k,lString[k],x);
}
}
}
package simphy;
import java.awt.*;
import java.awt.event.*;
class InputDialog extends Frame // Used with ControlMenu
{
TextField newValueText;
double x[];
public InputDialog(Simulation S,int k, String lString, double x[])
{
this.x = x;
setTitle("Dialog Box");
setSize(250,250);
setLocation(50,50);
setLayout(null);
Label label = new Label("Enter new " + lString);
label.setSize(150,20);
label.setLocation(50,20);
add(label);
Button b1 = new Button("Okay");
b1.addActionListener( new OkayClass(k,S));
Button b2 = new Button("Cancel");
b2.addActionListener( new CancelClass());
b1.setLocation(30,80);
b2.setLocation(150,80);
b1.setSize(70,20);
b2.setSize(70,20);
add(b1);
add(b2);
newValueText = new TextField(String.valueOf(x[k]));
newValueText.setSize(80,20);
newValueText.setLocation(50,50);
add(newValueText);
setVisible(true);
}
class OkayClass implements ActionListener
{
int k;
Simulation S;
public OkayClass(int k, Simulation S)
{
this.k = k;
this.S = S;
}
public void actionPerformed(ActionEvent e)
{
String s = newValueText.getText();
Double R = new Double(s.trim());
S.dialogAction(k,R.doubleValue());
x[k] = R.doubleValue();
setVisible(false);
dispose();
}
}
class CancelClass implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
setVisible(false);
dispose();
}
}
}
Table
package simphy;
import java.awt.*;
import java.text.*;
public class Table extends Frame {
protected double entry[];
int n;
public TextArea t;
DecimalFormat number[];
int FieldSize = 10;
public Table(String TableName, String h[],int FieldSize, boolean visibility) {
this.FieldSize = FieldSize;
n = h.length;
entry = new double[n];
number = new DecimalFormat[n];
setTitle(TableName);
setSize(90*n,500);
t = new TextArea();
add(t);
t.setEditable(true);
setVisible(visibility); // set visibility to false and use showTable to show all at once
setHeadings(h);
String pattern[] = new String[n];
for(int i = 0; i < n ; i++)
pattern[i] = "#.000";
setFormat(pattern,FieldSize);
}
public Table(String TableName, String h[]) { // sets up Table with default formats
this(TableName,h,10,true);
}
public Table(String TableName, String h[], int FieldSize) {
this(TableName,h,FieldSize,true);
}
public void showTable() {
setVisible(true);
}
public void setHeadings(String h[]) {
int len;
setFont(new Font("Monospaced",Font.BOLD,10));
for(int i = 0; i < n ; i++) {
len = h[i].length();
if(len < FieldSize)
for(int j = 0; j < FieldSize-len;j++) h[i] = " " + h[i];
t.append(h[i] + "\t");
}
t.append("\n" + "\n");
}
public void println(String S) {
t.append(S + "\n");
}
public void setFormat(String pattern[],int FieldSize) {
this.FieldSize = FieldSize;
for(int i = 0; i < n ; i++)
number[i] = new DecimalFormat(pattern[i]);
}
public void displayEntries() {
int len,Eloc;
String s;
setFont(new Font("Monospaced",Font.PLAIN,10));
for(int i = 0; i < n ; i++) {
if(Math.abs(entry[i]) < 1.0E7) {
s = number[i].format(entry[i]);
len = s.length();
}
else{
s = String.valueOf(entry[i]);
len = s.length();
Eloc = len;
for(int j = 0; j < len;j++)
if ( s.substring(j,j+1).equalsIgnoreCase("E"))Eloc = j;
s = s.substring(0,4) + s.substring(Eloc,len);
len = s.length();
}
if(len < FieldSize)
for(int j = 0; j < FieldSize-len;j++) s = " " + s;
t.append(s + "\t");
}
t.append("\n");
}
public void setEntry(int i, double x) {
entry[i] = x;
}
public void setEntries(double x0, double x1) {
entry[0] = x0;
entry[1] = x1;
}
public void setEntries(double x0, double x1, double x2) {
setEntries(x0,x1);
entry[2] = x2;
}
public void setEntries(double x0, double x1, double x2, double x3) {
setEntries(x0,x1,x2);
entry[3] = x3;
}
public void setEntries(double x0, double x1, double x2, double x3, double x4) {
setEntries(x0,x1,x2,x3);
entry[4] = x4;
}
}
Plot
package simphy;
import java.awt.*;
public class Plot extends Frame{
double scalex,scaley,xmin,ymin,xmax,ymax;
int nAxes;
String xLabel,yLabel;
int mg = 30;
int width,height;
int symbolSize;
String symbolType;
Image buffer;
Graphics b;
public Plot(String title, String xLabel, String yLabel, int nAxes,
double xmin,double xmax, double ymin, double ymax, int symbolSize,
String symbolType, int xsize, int ysize, int xloc, int yloc) {
this.nAxes = nAxes;
this.xLabel = xLabel;
this.yLabel = yLabel;
this.xmin = xmin;
this.ymin = ymin;
this.xmax = xmax;
this.ymax = ymax;
this.symbolSize = symbolSize;
setTitle(title);
setSize(xsize,ysize);
width = getSize().width;
height = getSize().height;
setLocation(xloc,yloc);
setVisible(true);
setScale();
buffer = createImage(getSize().width,getSize().height);
b = buffer.getGraphics();
setAxes();
}
public Plot(String title, String xLabel, String yLabel, int nAxes,
double xmin,double xmax, double ymin, double ymax,
int symbolSize, String symbolType) {
this(title, xLabel, yLabel,nAxes, xmin, xmax, ymin, ymax, symbolSize,
symbolType, 400, 400,150,150);
}
public Plot(String title, String xLabel, String yLabel, int nAxes,
double xmin,double xmax, double ymin, double ymax) {
this(title,xLabel,yLabel,nAxes,xmin,xmax,ymin,ymax,1,"dot",400,400,150,150);
}
public Plot(String title,double xmin,double xmax, double ymin, double ymax,
int xsize, int ysize) {
this(title,"","",0,xmin,xmax,ymin,ymax,1,"dot",xsize,ysize,150,150);
}
public Plot(String title,double xmin,double xmax, double ymin, double ymax,
int xsize, int ysize, int xloc, int yloc) {
this(title,"","",0,xmin,xmax,ymin,ymax,1,"dot",xsize,ysize,xloc,yloc);
}
public Plot(int nAxes,
double xmin,double xmax, double ymin, double ymax) {
this("Plot","x","y",nAxes,xmin,xmax,ymin,ymax,1,"dot",400,400,150,150);
}
private void setScale() {
if(xmax > xmin)
scalex = (getSize().width-2*mg)/(xmax-xmin);
else {
System.out.println("Error xmax not greater than xmin");
return;
}
if(ymax > ymin)
scaley = (getSize().height-2*mg)/(ymax-ymin);
else {
System.out.println("Error ymax not greater than ymin");
return;
}
}
public void setAxes() {
int mg = 30;
int ix,iy;
if(width != getSize().width || height != getSize().height) {
width = getSize().width;
height = getSize().height;
setScale();
}
b.clearRect(0,0,getSize().width,getSize().height);
switch (nAxes) { // draw axes and axis labels
case 1: b.drawLine(mg,size().height-mg,size().width-mg,size().height-mg);
b.drawString(xLabel,getSize().width/2,getSize().height-10);
break;
case 2: b.drawLine(mg,getSize().height-mg,mg,mg);
b.drawLine(mg,getSize().height-mg,getSize().width-mg,size().height-mg);
b.drawString(xLabel,getSize().width-2*mg,getSize().height-10);
b.drawString(yLabel,10,20);
break;
case 3: b.drawLine(mg,size().height-mg,size().width-mg,size().height-mg);
b.drawLine(size().width/2,size().height-mg,size().width/2,mg);
b.drawString(xLabel,getSize().width-2*mg,getSize().height-10);
b.drawString(yLabel,getSize().width/2,20);
break;
case 4: b.drawLine(mg,getSize().height/2,getSize().width-mg,getSize().height/2);
b.drawLine(getSize().width/2,size().height-mg,getSize().width/2,mg);
b.drawString(xLabel,getSize().width-2*mg,getSize().height/2+20);
b.drawString(yLabel,getSize().width/2,20);
break;
case 5: b.drawLine(mg,getSize().height/2,getSize().width-mg,getSize().height/2);
b.drawLine(mg,mg,mg,getSize().height-mg);
b.drawString(xLabel,getSize().width-2*mg,getSize().height/2+20);
b.drawString(yLabel,mg,20);
break;
}
Graphics g = getGraphics();
g.drawImage(buffer,0,0,this); // draw image onto screen
}
public void clearPoints() {
b.clearRect(0,0,getSize().width,getSize().height);
setAxes();
}
public void clear() {
b.clearRect(0,0,getSize().width,getSize().height);
}
public void plotPoints(double x[],double y[]) {
int ix,iy;
for(int i = 0; i < x.length; i++) { // plot points
ix = (int)((x[i]-xmin)*scalex) +mg;
iy = getSize().height - (int)((y[i]-ymin)*scaley) - mg;
if(symbolSize > 1) {
if(symbolType == "fillsquare")
b.fillRect(ix-symbolSize/2,iy-symbolSize/2,symbolSize,symbolSize);
else if(symbolType == "opensquare")
b.drawRect(ix-symbolSize/2,iy-symbolSize/2,symbolSize,symbolSize);
else if(symbolType == "opencircle")
b.drawOval(ix-symbolSize/2,iy-symbolSize/2,symbolSize,symbolSize);
else
b.fillOval(ix-symbolSize/2,iy-symbolSize/2,symbolSize,symbolSize);
}
else
b.drawLine(ix,iy,ix,iy);
}
Graphics g = getGraphics();
g.drawImage(buffer,0,0,this); // draw image onto screen
}
public void plotPoint(double x,double y) {
int ix,iy;
// plot point
ix = (int)((x-xmin)*scalex) +mg;
iy = getSize().height - (int)((y-ymin)*scaley) - mg;
if(symbolSize > 1) {
if(symbolType == "fillsquare")
b.fillRect(ix-symbolSize/2,iy-symbolSize/2,symbolSize,symbolSize);
else if(symbolType == "opensquare")
b.drawRect(ix-symbolSize/2,iy-symbolSize/2,symbolSize,symbolSize);
else if(symbolType == "opencircle")
b.drawOval(ix-symbolSize/2,iy-symbolSize/2,symbolSize,symbolSize);
else
b.fillOval(ix-symbolSize/2,iy-symbolSize/2,symbolSize,symbolSize);
}
else
b.drawLine(ix,iy,ix,iy);
Graphics g = getGraphics();
g.drawImage(buffer,0,0,this); // draw image onto screen
}
public void plotCurve(double x[],double y[]) {
int ix1,iy1,ix2,iy2;
ix1 = (int)((x[0]-xmin)*scalex) +mg;
iy1 = size().height - (int)((y[0]-ymin)*scaley) - mg;
for(int i = 1; i < x.length; i++) { // plot points
ix2 = (int)((x[i]-xmin)*scalex) +mg;
iy2 = size().height - (int)((y[i]-ymin)*scaley) - mg;
b.drawLine(ix1,iy1,ix2,iy2);
ix1 = ix2;
iy1 = iy2;
}
Graphics g = getGraphics();
g.drawImage(buffer,0,0,this); // draw image onto screen
}
public void setColor(String s) {
Color c = Color.black;
if(s == "red") c = Color.red;
else if(s == "blue") c = Color.blue;
else if(s == "black") c = Color.black;
else if(s == "green") c = Color.green;
else if(s == "yellow") c = Color.yellow;
else if(s == "white") c = Color.white;
else if(s == "magenta") c = Color.magenta;
else if(s == "cyan") c = Color.cyan;
else if(s == "orange") c = Color.orange;
else if(s == "pink") c = Color.pink;
else if(s == "random") c = new Color((int) (Math.random()*255),
(int) (Math.random()*255), (int) (Math.random()*255));
b.setColor(c);
}
public void paint(Graphics g) {
if(getSize().width != width || getSize().height != height) {
width = getSize().width;
height = getSize().height;
setScale();
buffer = createImage(getSize().width,getSize().height);
b = buffer.getGraphics();
}
g.drawImage(buffer,0,0,this); // draw image onto screen
}
}
WorldGraphics
package simphy;
/* Creates Frame for drawing on using world coordinates. y increases as you move up,
x increases as you move right. Unless otherwise specified methods use world
coordinates. */
import java.awt.*;
public class WorldGraphics extends Frame {
double scalex,scaley,xmin,ymin,xmax,ymax;
int width,height;
Image buffer;
Graphics b;
Color c = Color.black;
boolean toScreen = true; // draw to screen as well as buffer
public WorldGraphics(String title,
double xmin,double xmax, double ymin, double ymax, int size, int xLoc, int yLoc) {
this.xmin = xmin;
this.ymin = ymin;
this.xmax = xmax;
this.ymax = ymax;
double f = (ymax-ymin)/(xmax-xmin);
setTitle(title);
setSize(size,(int)(size*f));
width = getSize().width;
height = getSize().height;
setScale();
setLocation(xLoc,yLoc);
setVisible(true);
buffer = createImage(getSize().width,getSize().height);
b = buffer.getGraphics();
}
public WorldGraphics(String title,
double xmin,double xmax, double ymin, double ymax) {
// old version
this.xmin = xmin;
this.ymin = ymin;
this.xmax = xmax;
this.ymax = ymax;
double f = (ymax-ymin)/(xmax-xmin);
setTitle(title);
setSize(360,(int)(360*f));
width = getSize().width;
height = getSize().height;
setScale();
setLocation(200,100);
setVisible(true);
buffer = createImage(getSize().width,getSize().height);
b = buffer.getGraphics();
}
public void setScale() {
if(xmax > xmin) {
scalex = (getSize().width)/(xmax-xmin);
}
else {
System.out.println("Error xmax not greater than xmin");
return;
}
if(ymax > ymin) {
scaley = (getSize().height)/(ymax-ymin);
}
else {
System.out.println("Error ymax not greater than ymin");
return;
}
}
private int scrX(double x) {
return (int)((x-xmin)*scalex);
}
private int scrY(double y) {
return getSize().height - (int)((y-ymin)*scaley);
}
private int scrDX(double dx) {
return (int)(dx*scalex);
}
private int scrDY(double dy) {
return (int)(dy*scaley);
}
public void setToScreen(boolean toScreen) {
this.toScreen = toScreen;
}
public void drawLine(double x1, double y1, double x2, double y2) {
b.drawLine(scrX(x1),scrY(y1),scrX(x2),scrY(y2));
if (toScreen) repaint();
}
public void drawPoint(double x1, double y1) {
b.drawLine(scrX(x1),scrY(y1),scrX(x1),scrY(y1));
if (toScreen) repaint();
}
public void fillRect(double x, double y, double dx, double dy) {
b.fillRect(scrX(x),scrY(y)-scrDY(dy),scrDX(dx),scrDY(dy));
if (toScreen) repaint();
}
public void drawRect(double x, double y, double dx, double dy) {
b.drawRect(scrX(x),scrY(y)-scrDY(dy),scrDX(dx),scrDY(dy));
if (toScreen) repaint();
}
public void drawRect(int x, int y, int dx, int dy) { // uses screen coordinates
b.drawRect(x,y,dx,dy);
if (toScreen) repaint();
}
public void fillRect(int x, int y, int dx, int dy) { // uses screen coordinates
b.fillRect(x,y,dx,dy);
if (toScreen) repaint();
}
public void fillOval(double x, double y, double dx, double dy) {
b.fillOval(scrX(x),scrY(y)-scrDY(dy),scrDX(dx),scrDY(dy));
if (toScreen) repaint();
}
public void drawOval(double x, double y, double dx, double dy) {
b.drawOval(scrX(x),scrY(y)-scrDY(dy),scrDX(dx),scrDY(dy));
if (toScreen) repaint();
}
public void drawCircle(double x, double y, double r) {
b.drawOval(scrX(x)-scrDX(r),scrY(y)-scrDY(r),scrDX(2*r),scrDY(2*r));
if (toScreen) repaint();
}
public void fillCircle(double x, double y, double r) {
b.fillOval(scrX(x)-scrDX(r),scrY(y)-scrDY(r),scrDX(2*r),scrDY(2*r));
if (toScreen) repaint();
}
public void clearRect(double x, double y, double dx, double dy) {
b.clearRect(scrX(x),scrY(y)-scrDY(dy),scrDX(dx),scrDY(dy));
if (toScreen) repaint();
}
public void clearBuffer() {
b.clearRect(scrX(xmin),scrY(ymin)-scrDY(ymax-ymin),scrDX(xmax-xmin),scrDY(ymax-ymin));
}
public void clearLine(double x1, double y1, double x2, double y2) { // erase line
Color cSave = c;
b.setColor(getBackground());
drawLine(x1,y1,x2,y2);
b.setColor(cSave);
}
public void drawString(String s, double x, double y) {
b.drawString(s, scrX(x),scrY(y));
if (toScreen) repaint();
}
public void drawString(String s, int x, int y) { //uses screen coordinates
b.drawString(s,x,y);
if (toScreen) repaint();
}
public void setColor(int red, int green, int blue) {
c = new Color(red,green,blue);
b.setColor(c);
}
public void setColor(String s) {
if(s == "red") c = Color.red;
else if(s == "blue") c = Color.blue;
else if(s == "black") c = Color.black;
else if(s == "green") c = Color.green;
else if(s == "yellow") c = Color.yellow;
else if(s == "white") c = Color.white;
else if(s == "magenta") c = Color.magenta;
else if(s == "cyan") c = Color.cyan;
else if(s == "orange") c = Color.orange;
else if(s == "pink") c = Color.pink;
else if(s == "random") c = new Color((int) (Math.random()*255),
(int) (Math.random()*255), (int) (Math.random()*255));
b.setColor(c);
}
public void drawBuffer() {
Graphics g = getGraphics();
g.drawImage(buffer,0,0,this); // draw image onto screen, useful for animation
}
public void paint(Graphics g) {
if(getSize().width != width || getSize().height != height) {
width = getSize().width;
height = getSize().height;
setScale();
buffer = createImage(getSize().width,getSize().height);
b = buffer.getGraphics();
}
g.drawImage(buffer,0,0,this); // draw image onto screen
}
}
SimFormat
package simphy;
import java.text.DecimalFormat;
public abstract class SimFormat {
public static String dformat(double x, int d) {
DecimalFormat df = new DecimalFormat();
df.setMinimumIntegerDigits(1);
df.setMaximumFractionDigits(d);
df.setMinimumFractionDigits(d);
df.setGroupingUsed(false);
return df.format(x);
}
public static String dformat(double x) {
return dformat(x,3);
}
public static String eformat(double x, int d) {
if(x == 0)
return "0";
if(x < 0) {
double y = Math.log(-x)/Math.log(10);
int p = (int) y;
double dec = Math.pow(10,y-p);
if(dec <= 1)
return "-" + dformat(10*dec,d) + " E" + String.valueOf(p-1);
else
return "-" + dformat(dec,d) + " E" + String.valueOf(p);
}
else {
double y = Math.log(x)/Math.log(10);
int p = (int) y;
double dec = Math.pow(10,y-p);
if(dec <= 1)
return dformat(10*dec,d) + " E" + String.valueOf(p-1);
else
return dformat(dec,d) + " E" + String.valueOf(p);
}
}
public static String eformat(double x) {
return eformat(x,3);
}
public static String aformat(double x, int d, double min, double max) {
if(Math.abs(x) > max || Math.abs(x) < min)
return eformat(x,d);
else
return dformat(x,d);
}
public static String aformat(double x, double min, double max) {
return aformat(x,3,min,max);
}
public static String aformat(double x) {
return aformat(x,3,0.001,100);
}
}
Updated 20 May 2000.