Java Input for Chemical Symbols

This is our second (and perhaps last) attempt at creating a chemical symbol input device which would allow students to enter chemical formulii in the approximate form that textbooks use.
ChemSymIn is written as an applet, which means that one needs a <APPLET></APPLET> line of html code to activate it.
import java.awt.*;
import java.applet.*;
import java.util.*;
import java.io.*;

public class ChemSymIn extends  Applet {

   public void init() { 
	resize(550,300); 
	setLayout(new BorderLayout());

  

 Panel p = new Panel();
   p.setLayout(new FlowLayout());
   p.add(new Button("Submit for Grading")); 
   p.add(new Button("ReDisplay")); 
   this.add("North", p);


   cd_disp = new ChemSymInCanv2();
   this.add("Center", cd_disp);
	cd_disp.update("Click `ReDisplay' to Start");
	start();
   }
   
	public boolean handleEvent(Event evt) {  
		if (evt.id == Event.WINDOW_DESTROY
			&& evt.target == this) System.exit(0);//for the Help about
      return super.handleEvent(evt);
   }
   

	public boolean keyDown(Event evt, int key){
		if(DeBug){	
			System.out.println("Event (keydown) = "+evt);
			System.out.println("key = "+ key);
			}	
		if (key == Event.LEFT || key == 8 || key == 127) {
			StringBuffer new_str = new StringBuffer(100);
			new_str.append(s1);
			if(DeBug) System.out.println("s1 before delete = "+s1);
			int len = new_str.length();
			if(new_str.charAt(len-1) == '}')new_str.setLength(len-1-3);
			else new_str.setLength(len-1);
			s1 = new_str.toString();
			if(DeBug) System.out.println("s1 after delete = "+s1);
			cd_disp.update(s1);
			return true;
			}
		else
		if (key == Event.UP){
			cd_disp.setsuper(1);
			return true;
			}
		else
		if(key == Event.DOWN){
			cd_disp.setsuper(-1);
			return true;
			}
		else
		if( key >= 40 && key <= 122  ){
			StringBuffer new_str = new StringBuffer(100);
			StringBuffer cd = new StringBuffer(1);
			char key_char = (char) key;//cast key -> char
			cd.append(key_char);//need to convert to character
			if(DeBug){
				System.out.println("s1 before appending key_char = "+s1);
				System.out.println("s1 before appending key_char = "+s1);
				}
			new_str.append(s1);
			if(cd_disp.state() == 1){new_str.append("^{"+cd+"}");}
			else
			if(cd_disp.state() == -1){new_str.append("_{"+cd+"}");}
			else{ new_str.append(cd);}
			s1 = new_str.toString();
			cd_disp.update(s1);
			return true;
			}
		return false;
	}
		
	public boolean action(Event evt, Object arg) {
		String ans = getParameter("answer");
		if(DeBug){	
			System.out.println("Event (action) = "+evt);
			System.out.println("arg = "+ arg);
			}
	   if (arg.equals("Submit for Grading")){
			if (s1.equals(ans)){
				StringBuffer cd_str = new StringBuffer(100);
				cd_str.append (" YES ");
				String s9 = cd_str.toString();
				cd_disp.update(s9);
				return true;
				}
			else{
				StringBuffer cd_str = new StringBuffer(100);
				cd_str.append (" NO ");
				String s9 = cd_str.toString();
				cd_disp.update(s9);
				return true;
				}
			}
		if (arg.equals("ReDisplay")){
			cd_disp.clear();
			StringBuffer cd_str = new StringBuffer(100);
			cd_str.append(s1);
			s1 = cd_str.toString();
			cd_disp.update(s1);
			return true;
			}
		else
		return false;
	}




	public boolean DeBug = false;
        public TextField display;
	public String ans;
        private TextField minuteField;
	public ChemSymInCanv2 cd_disp;
        public static StringBuffer cd_str;
        public String s1 = "";
	public Checkbox sup;
	public Checkbox sub;
	public Checkbox normal;
   
}



class ChemSymInCanv2 extends Canvas {
	public void paint(Graphics g )
   {
	Font f = new Font("TimesRoman",Font.BOLD,48);
	Font n = new Font("TimesRoman",Font.BOLD,16);
	FontMetrics fm = g.getFontMetrics(f);
	FontMetrics nm = g.getFontMetrics(n);
	g.setFont(f);
	Dimension d = size();
	int client_width = d.width ;
	int sup_sub = 0;
	int inc = 0;
	int h_mul = 1;
	int i,j = 0;
	boolean test;
	int client_height = d.height;
	int cx = client_width /2;
	int cy = client_height/2;

	StringBuffer t = new StringBuffer(100);
	t.insert(0,s1);//copy s1 to t
	String s6 = t.toString();//convert t back to String s6



	for (i=0;i<s6.length();i++){
		if (s6.indexOf("}") != -1){
				if(DeBug){System.out.println("index = "+s6.indexOf("^{"));}
				if (s6.indexOf("^{",i) == i || s6.indexOf("_{",i)==i){
				if (s6.indexOf("^{",i) == i ) sup_sub = 1;
				if (s6.indexOf("_{",i) == i ) sup_sub = -1;
					i = i +2;
					if(DeBug){System.out.println("in superscript (after i+2), line, i = "+i);}
					j = fm.getHeight()*h_mul/2;
					test = s6.substring(i,i+1).equals("}"); 	
				
					while ( !test){
						g.drawString(s6.substring(i,i+1),4+inc,cy-j*sup_sub);
						inc += fm.stringWidth(s6.substring(i,i+1));//width of font???
						i++;
						test = s6.substring(i,i+1).equals("}"); 	
						}
					}
				else {
					sup_sub = 0;
					if(DeBug)System.out.println("in Default line, i = "+i);
					j = 0;
					if(DeBug){
						System.out.println("s6.substring("+i+") = "+s6.substring(i,i+1));
						System.out.println("s6 = "+s6);
						}
					g.drawString(s6.substring(i,i+1),4+inc,cy+j*sup_sub);
					inc += fm.stringWidth(s6.substring(i,i+1));//width of font???
					if(DeBug)System.out.println("inc = "+inc);
					}
				}
			else {
				g.drawString(s6,4,cy);	
				break ;
				}
			}
	int charWidth = fm.charWidth('W');
	int maxChars = client_width / charWidth;
	g.setColor(Color.yellow);
	g.drawRect(4,cy-fm.getHeight()/2,client_width-8,30);
	g.setColor(Color.green);
	if(state() == 0) g.drawRect(4,cy-fm.getHeight()/2,client_width-8,30);
	if(state() == 1)g.drawRect(4,cy-2*fm.getHeight()/2,client_width-8,30);
	if(state() == -1)g.drawRect(4,cy,client_width-8,30);
	g.setColor(Color.blue);
	g.setFont(n);
	g.drawString("Enter characters using up and down arrows for `super' and `sub' scripts.",1,12);	
	g.drawString("`BackSpace', `Left Arrow', and `Delete' all remove last character.",1,12+nm.getHeight());	
	g.drawString("`ReDisplay' after `Submit for Grading' to see formula again.",1,12+2*nm.getHeight());	
	g.setColor(Color.green);
	g.drawString("Next character appears in Green Box.",1,12+9*nm.getHeight());	
	g.setColor(Color.yellow);
	if(First == 0) g.drawString("Choose `ReDisplay' to start.",300,12+9*nm.getHeight());	
	First = 1;
	g.setFont(f);
	g.setColor(Color.black);
   }
   
   public void setsuper(int flag) {  
      ChemSymInCanv2.super_flag = state()+flag;
		if(ChemSymInCanv2.super_flag == 2)ChemSymInCanv2.super_flag = -1;
		if(ChemSymInCanv2.super_flag == -2)ChemSymInCanv2.super_flag = 1;
      repaint();
		}
  
	public int state() {
		if (ChemSymInCanv2.super_flag == 1) return (1);
		else if (ChemSymInCanv2.super_flag == -1) return (-1);
		else return (0);
		}

   public void update(String args) {  
		ChemSymInCanv2.s1 = args;
		if(DeBug)System.out.println("args in subroutine update = "+args);
      repaint();
		}

   public void clear() {  
		ChemSymInCanv2.s1 = "";
		repaint();
  	 }

   
	public boolean DeBug = false;
   public StringBuffer c1;
	public String s1 = "";
	public int super_flag;
	public int First = 0;
	

}

Here is an annotated version of the above, commented to indicate what is going on.

import java.awt.*;
import java.applet.*;
import java.util.*;
import java.io.*;

public class ChemSymIn extends  Applet {

   public void init() { 
	resize(550,300); 
	setLayout(new BorderLayout());

The coding (above) first makes available subroutines from various subroutine libraries (fortran terminology, sorry). Next, the code tells the system how big a Java display is going to be created. Finally, the code says that we will be using a BorderLayout, i.e., one which uses `North', `South', etc., as indicators of position.
 Panel p = new Panel();
   p.setLayout(new FlowLayout());
   p.add(new Button("Submit for Grading")); 
   p.add(new Button("ReDisplay")); 
   this.add("North", p);

We have here created a new panel, called p, whose internal layout fill be a FlowLayout, i.e., left to right sequential. It consists of two buttons, one for submission, and one for clearing the display and re-displaying whatever is currently contained in the `answer string'. The last line adds p to the main BorderLayout, placing it at the top of the display.
   cd_disp = new ChemSymInCanv2();
Below, you will see where ChemSymInCanv2 is created.
   this.add("Center", cd_disp);
We have just added the ChemSymCanv2 display, called cd_disp, to the main display, placing it in the center!
	cd_disp.update("Click `ReDisplay' to Start");
	start();
Here we insert a message into the `answer string' which will show the first time the applet is invoked, and never again.
   }
   
	public boolean handleEvent(Event evt) {  
		if (evt.id == Event.WINDOW_DESTROY
			&& evt.target == this) System.exit(0);//for the Help about
      return super.handleEvent(evt);
   }
   

	public boolean keyDown(Event evt, int key){
		if(DeBug){	
			System.out.println("Event (keydown) = "+evt);
			System.out.println("key = "+ key);
			}	
Next, we are going to handle all left moving keys the same, i.e., Delete, BackSpace, and Left Arrow keys are handled here:
		if (key == Event.LEFT || key == 8 || key == 127) {
			StringBuffer new_str = new StringBuffer(100);
			new_str.append(s1);
			if(DeBug) System.out.println("s1 before delete = "+s1);
			int len = new_str.length();
			if(new_str.charAt(len-1) == '}')new_str.setLength(len-1-3);
			else new_str.setLength(len-1);
			s1 = new_str.toString();
			if(DeBug) System.out.println("s1 after delete = "+s1);
			cd_disp.update(s1);
			return true;
			}
		else
		if (key == Event.UP){
			cd_disp.setsuper(1);
			return true;
			}
		else
		if(key == Event.DOWN){
			cd_disp.setsuper(-1);
			return true;
			}
		else
		if( key >= 40 && key <= 122  ){
			StringBuffer new_str = new StringBuffer(100);
			StringBuffer cd = new StringBuffer(1);
			char key_char = (char) key;//cast key -> char
			cd.append(key_char);//need to convert to character
			if(DeBug){
				System.out.println("s1 before appending key_char = "+s1);
				System.out.println("s1 before appending key_char = "+s1);
				}
			new_str.append(s1);
			if(cd_disp.state() == 1){new_str.append("^{"+cd+"}");}
			else
			if(cd_disp.state() == -1){new_str.append("_{"+cd+"}");}
			else{ new_str.append(cd);}
			s1 = new_str.toString();
			cd_disp.update(s1);
			return true;
			}
		return false;
	}
		
	public boolean action(Event evt, Object arg) {
		String ans = getParameter("answer");
		if(DeBug){	
			System.out.println("Event (action) = "+evt);
			System.out.println("arg = "+ arg);
			}
	   if (arg.equals("Submit for Grading")){
			if (s1.equals(ans)){
				StringBuffer cd_str = new StringBuffer(100);
				cd_str.append (" YES ");
				String s9 = cd_str.toString();
				cd_disp.update(s9);
				return true;
				}
			else{
				StringBuffer cd_str = new StringBuffer(100);
				cd_str.append (" NO ");
				String s9 = cd_str.toString();
				cd_disp.update(s9);
				return true;
				}
			}
		if (arg.equals("ReDisplay")){
			cd_disp.clear();
			StringBuffer cd_str = new StringBuffer(100);
			cd_str.append(s1);
			s1 = cd_str.toString();
			cd_disp.update(s1);
			return true;
			}
		else
		return false;
	}




	public boolean DeBug = false;
        public TextField display;
	public String ans;
        private TextField minuteField;
	public ChemSymInCanv2 cd_disp;
        public static StringBuffer cd_str;
        public String s1 = "";
	public Checkbox sup;
	public Checkbox sub;
	public Checkbox normal;
   
}



class ChemSymInCanv2 extends Canvas {
	public void paint(Graphics g )
   {
	Font f = new Font("TimesRoman",Font.BOLD,48);
	Font n = new Font("TimesRoman",Font.BOLD,16);
	FontMetrics fm = g.getFontMetrics(f);
	FontMetrics nm = g.getFontMetrics(n);
	g.setFont(f);
	Dimension d = size();
	int client_width = d.width ;
	int sup_sub = 0;
	int inc = 0;
	int h_mul = 1;
	int i,j = 0;
	boolean test;
	int client_height = d.height;
	int cx = client_width /2;
	int cy = client_height/2;

	StringBuffer t = new StringBuffer(100);
	t.insert(0,s1);//copy s1 to t
	String s6 = t.toString();//convert t back to String s6



	for (i=0;i<s6.length();i++){

		if (s6.indexOf("}") != -1){
				if(DeBug){System.out.println("index = "+s6.indexOf("^{"));}
				if (s6.indexOf("^{",i) == i || s6.indexOf("_{",i)==i){
				if (s6.indexOf("^{",i) == i ) sup_sub = 1;
				if (s6.indexOf("_{",i) == i ) sup_sub = -1;
					i = i +2;
					if(DeBug){System.out.println("in superscript (after i+2), line, i = "+i);}
					j = fm.getHeight()*h_mul/2;
					test = s6.substring(i,i+1).equals("}"); 	
				
					while ( !test){
						g.drawString(s6.substring(i,i+1),4+inc,cy-j*sup_sub);
						inc += fm.stringWidth(s6.substring(i,i+1));//width of font???
						i++;
						test = s6.substring(i,i+1).equals("}"); 	
						}
					}
				else {
					sup_sub = 0;
					if(DeBug)System.out.println("in Default line, i = "+i);
					j = 0;
					if(DeBug){
						System.out.println("s6.substring("+i+") = "+s6.substring(i,i+1));
						System.out.println("s6 = "+s6);
						}
					g.drawString(s6.substring(i,i+1),4+inc,cy+j*sup_sub);
					inc += fm.stringWidth(s6.substring(i,i+1));//width of font???
					if(DeBug)System.out.println("inc = "+inc);
					}
				}
			else {
				g.drawString(s6,4,cy);	
				break ;
				}
			}
	int charWidth = fm.charWidth('W');
	int maxChars = client_width / charWidth;
	g.setColor(Color.yellow);
	g.drawRect(4,cy-fm.getHeight()/2,client_width-8,30);
	g.setColor(Color.green);
	if(state() == 0) g.drawRect(4,cy-fm.getHeight()/2,client_width-8,30);
	if(state() == 1)g.drawRect(4,cy-2*fm.getHeight()/2,client_width-8,30);
	if(state() == -1)g.drawRect(4,cy,client_width-8,30);
	g.setColor(Color.blue);
	g.setFont(n);
	g.drawString("Enter characters using up and down arrows for `super' and `sub' scripts.",1,12);	
	g.drawString("`BackSpace', `Left Arrow', and `Delete' all remove last character.",1,12+nm.getHeight());	
	g.drawString("`ReDisplay' after `Submit for Grading' to see formula again.",1,12+2*nm.getHeight());	
	g.setColor(Color.green);
	g.drawString("Next character appears in Green Box.",1,12+9*nm.getHeight());	
	g.setColor(Color.yellow);
	if(First == 0) g.drawString("Choose `ReDisplay' to start.",300,12+9*nm.getHeight());	
	First = 1;
	g.setFont(f);
	g.setColor(Color.black);
   }
   
   public void setsuper(int flag) {  
      ChemSymInCanv2.super_flag = state()+flag;
		if(ChemSymInCanv2.super_flag == 2)ChemSymInCanv2.super_flag = -1;
		if(ChemSymInCanv2.super_flag == -2)ChemSymInCanv2.super_flag = 1;
      repaint();
		}
  
	public int state() {
		if (ChemSymInCanv2.super_flag == 1) return (1);
		else if (ChemSymInCanv2.super_flag == -1) return (-1);
		else return (0);
		}

   public void update(String args) {  
		ChemSymInCanv2.s1 = args;
		if(DeBug)System.out.println("args in subroutine update = "+args);
      repaint();
		}

   public void clear() {  
		ChemSymInCanv2.s1 = "";
		repaint();
  	 }

   
	public boolean DeBug = false;
   public StringBuffer c1;
	public String s1 = "";
	public int super_flag;
	public int First = 0;
	

}

Test the above html code.
Continue on to next section (prelim2).
Return to the last section (intro).
Return to the main book TOC.