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.