Much of the syntax of Java is the same as C and C++. One big difference is
that Java does not have pointers. However, the biggest difference is that you
must write object oriented code in Java. Procedural pieces of code can only be
embedded in objects. In this tutorial we assume you have some familiarity with
a programming language. Some familiarity with the syntax of C or C++ will also
be useful.
Application | Applet | GUI Application | GUI Applet |
Events | Animation | Ising Model |
Application
The features of the Java application included in the above program include:
class ExampleApplication{
public static void main( String args[] ) {
double m, a, force;
m = 2.0; // mass in kilograms
a = 4.0; // acceleration in mks units
force = m*a; // force in newtons
System.out.println(force);
}
}
The structure of an applet is slightly different than that of an application.
Below we show the same program, but written as an applet. Applet
Applets are run by web pages. Below we show a simple HTML document which could
be used to run the above applet. Note that before the applet can be run the
program must be translated into byte code which is placed in the file
ExampleApplet.class. The dimensions of the window where the applet will
appear are defined in the web page. The web page also allows the user to
see the source code for the applet.
The main advantage of Java for our purposes is the easy to use graphical user
interface(GUI) that comes with the language and that is platform independent.
The application below shows how to set up your own interface and one way to
input and output your results.
The above application can be rewritten as an applet, as shown below.
The following applet shows you how to deal with a number of other types of
events. After each event occurs, the program clears the window and prints a
message listing the type of event.
The program above is useful for carrying out a calculation, waiting for an
event, and then carrying out another calculation. However, frequently we want
to be able to interrupt a calculation while it is running. For example, we
might have a simulation running and we want to interrupt the simulation to
change a parameter. The following applet shows how to do this within the
context of an animation. It is a simulation of a ball bouncing around in a
box(defined by the window) with no air friction. When the user clicks the
mouse, the ball moves to the position of the mouseclick. The simulation also
allows the user to resize the window, so that the ball reflects off the new
edges of the new window.
The above program includes a number of new features:
Our final example shows an Ising model simulation based on Program
Ising in Chapter 17 of Gould & Tobochnik.
The above program includes most of what one needs to run simulations in physics
with user interaction. The main new features of the program are listed below.
The features of the Java applet that are different than the application are:
import java.awt.*;
import java.applet.Applet;
public class ExampleApplet extends Applet{
public void paint( Graphics g ) {
double m, a, force;
m = 2.0; // mass in kilograms
a = 4.0; // acceleration in mks units
force = m*a; // force in newtons
g.drawString(String.valueOf(force), 30, 30 );
}
}
<HTML>
<HEAD>
<TITLE>Example Applet</TITLE>
</HEAD>
<HR>
<BODY
<APPLET code="ExampleApplet.class" width=200 height=200>
</APPLET>
<hr>
<a href="ExampleApplet.java">The source.</a>
</BODY>
</HTML>
The features of the Java application included in the above program include:
import java.awt.*;
import java.applet.*;
class GuiApplication {
public static void main( String args[] ) {
MyFrame frame = new MyFrame();
frame.setTitle("Input Example");
frame.resize(500,300);
frame.init();
frame.show();
}
}
class MyFrame extends Frame {
double m = 0; // mass
TextField mText,fText; // textfield to enter mass and output force
Label mLabel, fLabel; // label for mass and force textfield
public void init() {
setLayout(null); // don't use deffault layout
setBackground (Color.lightGray);
mText = new TextField(""); // field to enter mass value
mText.reshape(20,20,50,20); // locate at 20,20; 50 pixels wide and 20 pixels high
add(mText); // add field to window
mLabel = new Label("mass");
mLabel.reshape(20,40,50,20); //locate label below textfield
add(mLabel); //add label to window
fText = new TextField(""); // field to output force value
fText.reshape(80,20,50,20); // locate at 80,20; 50 pixels wide and 20 pixels high
add(fText); // add field to window
fLabel = new Label("force");
fLabel.reshape(80,40,50,20); //locate label below textfield
add(fLabel); //add label to window
}
public void product() {
double a = 5.0,force;
force = m*a; // m is found from handle event routine below
fText.setText(String.valueOf(force));
}
public boolean handleEvent(Event e) {
Rectangle mRect = mText.bounds(); // boundary of mass textfield
if ((e.x == mRect.x) && (e.y == mRect.y)) // text entered in mass textfield
{
Double M = new Double(mText.getText ()); // convert string to Double object
m = M.doubleValue(); // get value of mass from Double object
product();
return (true);
}
else if (e.id == Event.WINDOW_DESTROY) // only needed for application
{
System.exit(0);
return(true);
}
return super.handleEvent(e); // take care of all other events
}
}
import java.awt.*;
import java.applet.*;
public class GuiApplet extends Applet{
double m = 0; // mass
TextField mText,fText; // textfield to enter mass and output force
Label mLabel, fLabel; // label for mass and force textfield
public void init(){
setLayout(null); // don't use deffault layout
setBackground (Color.lightGray);
mText = new TextField(""); // field to enter mass value
mText.reshape(20,20,50,20); // locate at 20,20; 50 pixels wide and 20 pixels high
add(mText); // add field to window
mLabel = new Label("mass");
mLabel.reshape(20,40,50,20); //locate label below textfield
add(mLabel); //add label to window
fText = new TextField(""); // field to output force value
fText.reshape(80,20,50,20); // locate at 80,20; 50 pixels wide and 20 pixels high
add(fText); // add field to window
fLabel = new Label("force");
fLabel.reshape(80,40,50,20); //locate label below textfield
add(fLabel); //add label to window
}
public void product() {
double a = 5.0,force;
force = m*a; // m is found from handle event routine below
fText.setText(String.valueOf(force));
}
public boolean handleEvent(Event e) {
Rectangle mRect = mText.bounds(); // boundary of mass textfield
if ((e.x == mRect.x) && (e.y == mRect.y)) // text entered in mass textfield
{
Double M = new Double(mText.getText ()); // convert string to Double object
m = M.doubleValue(); // get value of mass from Double object
product();
return (true);
}
return super.handleEvent(e); // take care of all other events
}
}
import java.applet.Applet;
import java.awt.*;
import java.util.*;
public class HandleApplet extends Applet{
int xMouse, yMouse; // Current position of the mouse.
int xWindow, yWindow; // Window width and height.
String sMessage = " ";
public void init (){
xMouse = 0;
yMouse = 0;
xWindow = size().width;
yWindow = size().height;
setBackground (Color.lightGray);
}
public boolean handleEvent(Event evt){
if (evt.id == Event.MOUSE_DOWN)
{
sMessage = "Mouse Down";
xMouse = evt.x;
yMouse = evt.y;
repaint ();
return(true);
}
else if (evt.id == Event.MOUSE_UP)
{
sMessage = "Mouse Up";
xMouse = evt.x;
yMouse = evt.y;
repaint ();
return(true);
}
else if (evt.id == Event.MOUSE_MOVE)
{
sMessage = "Mouse Move";
xMouse = evt.x;
yMouse = evt.y;
repaint ();
return(true);
}
else if (evt.id == Event.MOUSE_DRAG)
{
sMessage = "Mouse Drag";
xMouse = evt.x;
yMouse = evt.y;
repaint ();
return(true);
}
else if (evt.id == Event.KEY_PRESS)
{
sMessage = "Key Pressed";
repaint ();
return(true);
}
else if (evt.id == Event.KEY_ACTION)
{
sMessage = "Hot Key Pressed";
repaint ();
return(true);
}
return (super.handleEvent(evt));
}
public void paint (Graphics g){
g.clearRect (0, 0, xWindow, yWindow);
g.drawString (sMessage, xMouse, yMouse);
}
}
import java.awt.*; import java.applet.*;
public class fall extends Applet implements Runnable
{
Thread runner;
int x,y; // ball location
Image buffer;
int curw,curh; // window width and height
int accel = 4,vx,vy;
int bsize = 20; //ball size in pixels
int bsize1 = bsize + 1;
public void init() {
x = y = bsize; //initial conditions
vx = 6;
vy = 0;
}
public void start() {
runner = new Thread(this);
runner.start();
}
public void stop() {
runner.stop();
}
public void run() {
while (true) {
if ((buffer == null) || ( curw!= size().width) || (curh!= size().height))
{
buffer = createImage(size().width, size().height); // create graphics buffer
curw = size().width;
curh = size().height;
}
Rectangle oldRect = new Rectangle(x,y,bsize1,bsize1);
x += vx;
y += vy + 0.5*accel; // midpoint algorithm which is exact for constant acceleration
vy += accel;
Rectangle newRect = new Rectangle(x,y,bsize1,bsize1);
Rectangle r = newRect.union(oldRect);
Graphics g = buffer.getGraphics();
g.clipRect(r.x,r.y,r.width,r.height);
update(g);
g = getGraphics();
g.clipRect(r.x,r.y,r.width,r.height);
g.drawImage(buffer,0,0,this);
if (x <= 0 && vx < 0)
vx = -vx;
else if (x + bsize >= size().width && vx > 0)
vx = -vx;
if (y <= 0 && vy < 0)
vy = -vy;
else if (y + bsize >= size().height && vy > 0)
vy = -vy;
try {Thread.sleep(25);} // delay 25 msec between updates
catch (InterruptedException e){};
}
}
public boolean handleEvent(Event evt){
if (evt.id == Event.MOUSE_DOWN)
{
Graphics g = getGraphics();
g.clearRect (0, 0, size().width, size().height); // clear window
x = evt.x;
y = evt.y;
repaint(); // redraw window
return(true);
}
return (super.handleEvent(evt));
}
public void paint( Graphics g ) {
g.setColor(Color.red);
g.fillOval(x,y,bsize,bsize);
g.setColor(Color.blue);
g.drawString("Free Fall in a box",30,10); // title
}
}
import java.applet.*;
import java.awt.*;
import java.util.*;
public class isingApplet extends Applet implements Runnable
/***************************************************************************
2-d Ising Model simulation - Java version of Program Ising, page 575
of An Intorduction to Computer Simulation Methods by Harvey Gould and
Jan Tobochnik, Addison-Wesley, 1996.
***************************************************************************/
{
int L = 20; // dimension of lattice
int N = L*L; // number of spins
int spin[][] = new int[L][L]; // array of walker coordinates
double w[] = new double[10]; // Boltzmann weigts
int t = 0; // time in MCS per spin
double T = 2.269; // initial temperature = Tc
Button bhot,bcold,bstop,bcont;
Thread runner;
boolean running = false; // true if simulation is running
Scrollbar sTemp;
TextField tTemp,tTime;
TextField tMag,tChi,tEner,tSH,tAccept;
Label lTemp;
int x,y; // current spin coordinates
int shift=100; // x and y location of lattice corner
int wcell = 5; // cell width
double M = 0,M2 = 0,E = 0,E2 = 0;
double Accept;
/***************************************************************************/
public void init (){
// set up window with buttons, textfields and scrollbar
setLayout(null);
setBackground (Color.lightGray);
tTime = new TextField ("t = " + String.valueOf(t));
tTime.reshape(10,10,50,20);
add(tTime);
bhot = new Button("start hot"); // add buttons
bhot.reshape(40,50,80,20);
add(bhot);
bcold = new Button("start cold");
bcold.reshape(140,50,80,20);
add(bcold);
bstop = new Button("stop");
bstop.reshape(240,50,80,20);
add(bstop);
bcont = new Button("continue");
bcont.reshape(340,50,80,20);
add(bcont);
lTemp = new Label("Temperature"); // Temperature Label
lTemp.reshape(200,10,100,20);
add(lTemp);
// Temperature Scrollbar
sTemp = new Scrollbar (Scrollbar.HORIZONTAL,(int) (100.0*T),5,0,500);
sTemp.reshape(280,10,100,20);
add(sTemp);
tTemp = new TextField (String.valueOf(T)); // Temperture Textfield
tTemp.reshape(400,10,50,20);
add(tTemp);
boltzmann();
// Textfields for output of averages
tMag = new TextField ("M/N = ");
tMag.reshape(10,230,150,20);
add(tMag);
tChi = new TextField ("Susc = ");
tChi.reshape(10,260,150,20);
add(tChi);
tEner = new TextField ("E/N = ");
tEner.reshape(190,230,150,20);
add(tEner);
tSH = new TextField ("C = ");
tSH.reshape(190,260,150,20);
add(tSH);
tAccept = new TextField ("Acceptance Ratio = ");
tAccept.reshape(370,230,100,30);
add(tAccept);
}
public void start(){ // start thread
runner = new Thread(this);
runner.start();
}
public void stop(){ // stop thread
runner.stop();
}
public void run(){ // run thread
while(true)
{
if (running) // check to see if stop button pushed
{
MonteCarlo();
averages();
} //end if
try {Thread.sleep(250);} // check for events
catch (InterruptedException e){};
} //end while
}
public void MonteCarlo(){
int dE;
for (int i = 1;i <= N;i++) // Begin Monte Carlo code
{
x = (int) (L*Math.random()); // random number between 0 and L-1
y = (int) (L*Math.random());
dE = spin[x][y]*(spin[pbc(x-1)][y] + spin[pbc(x+1)][y]
+ spin[x][pbc(y-1)] + spin[x][pbc(y+1)]);
if(w[dE+4] > Math.random())
{
spin[x][y] = -spin[x][y]; // accept flip
drawSpin();
Accept++;
}
}
t++; // increment time
}
public void drawSpin() // draw spins
{
Graphics g = getGraphics();
if(spin[x][y] == 1)
g.setColor(Color.red);
else
g.setColor(Color.blue);
g.fillRect(shift+x*wcell,shift+y*wcell,wcell,wcell);
g.dispose();
}
public void averages()
{
double m=0,e=0,SH,Chi;
for(int i=0;i < L; i++)
for(int j=0;j < L; j++)
{
m += spin[i][j];
e -= spin[i][j]*(spin[i][pbc(j+1)] + spin[pbc(i+1)][j]);
}
M += m;
M2 += m*m;
E += e;
E2 += e*e;
Chi = (1.0/(T*N))*((M2/t) - (M/t)*(M/t));
SH = (1.0/(T*T*N))*((E2/t) - (E/t)*(E/t));
// Print averages
tTime.setText("t = " + String.valueOf(t));
tMag.setText("Mag/N = " + String.valueOf(M/(t*N)).substring(0,5));
tChi.setText("Susc. = " + String.valueOf(Chi));
tEner.setText("E/N = " + String.valueOf(E/(t*N)));
tSH.setText("C = " + String.valueOf(SH));
tAccept.setText("Acceptance Ratio = " + String.valueOf(Accept/(t*N)));
}
public int pbc(int s) { // periodic boundary conditions
if(s == -1)
return(L-1);
else if(s == L)
return(0);
else
return(s);
}
public void boltzmann(){
for(int i=-4;i <= 4; i++)
w[i+4] = Math.exp(-2.0*i/T);
}
public boolean handleEvent(Event evt){
Rectangle rectcont = bcont.bounds();
Rectangle recthot = bhot.bounds();
Rectangle rectcold = bcold.bounds();
Rectangle rectstop = bstop.bounds();
Rectangle rectTemp = tTemp.bounds();
if ( (evt.x == rectcont.x) && (evt.y == rectcont.y)) // continue
{
running = true;
return(true);
}
else if ( (evt.x == recthot.x) && (evt.y == recthot.y)) // start hot
{
for (x = 0;x < L;x++)
for (y = 0;y < L;y++)
{
if(Math.random() > 0.5)
spin[x][y] = 1;
else
spin[x][y] = -1;
drawSpin();
}
running = true;
return(true);
}
else if ( (evt.x == rectcold.x) && (evt.y == rectcold.y)) // start cold
{
for (x = 0;x < L;x++)
for (y = 0;y < L;y++)
{
spin[x][y] = -1;
drawSpin();
}
running = true;
return(true);
}
else if ( (evt.x == rectstop.x) && (evt.y == rectstop.y)) // stop
{
running = false;
return(true);
}
else if ((evt.id == Event.SCROLL_ABSOLUTE) || (evt.id == Event.SCROLL_LINE_UP)
|| (evt.id == Event.SCROLL_LINE_DOWN) || (evt.id == Event.SCROLL_PAGE_UP)
|| (evt.id == Event.SCROLL_PAGE_DOWN) )
{
T = (double) ((((Integer) evt.arg).intValue())/100.0);
tTemp.setText(String.valueOf(T));
t = 0;
M = M2 = E = E2 = Accept = 0;
boltzmann();
return(true);
}
else if ( (evt.x == rectTemp.x) && (evt.y == rectTemp.y)) // stop
{
Double Td = new Double(tTemp.getText());
T = Td.doubleValue();
sTemp.setValue( (int) (T*100));
t = 0;
M = M2 = E = E2 = Accept = 0;
boltzmann();
return(true);
}
return (super.handleEvent(evt)); //default handling of all other events
}
}