Introduction to Java

Java is a multiplatform object oriented programming language that can be used to create applications or applets. Applications are programs that perform the same functions as those written in other programming languages. Applets are programs that are embedded in a Web page and thus can be accessed over the Internet. Java has a built in application programming interface(API) that works under any operating system. When a program is compiled, a byte code is produced which can be read and executed by any software that can run Java.

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
Below we show a simple Java application which multiplies two numbers and prints their product. This program is the Java version of Program product in Chapter 2 of Gould & Tobochnik.

Application

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 features of the Java application included in the above program include:

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

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 );
 }
}
The features of the Java applet that are different than the application are:

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.

<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 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.

 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
     }
}

The features of the Java application included in the above program include:

The above application can be rewritten as an applet, as shown below.

 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
     }
}

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.

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);
      }
  }

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.

 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
	  }
}

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.

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
      }
}

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.