import java.applet.*;import java.awt.*;import java.awt.event.*;import java.io.*;import java.net.*;import java.util.*;public class BrailleApplet extends Applet implements ActionListener, ItemListener,                                                      TextListener, KeyListener, Runnable {  Brailler brailler = new Brailler(3,3,6,6,18,25);  BrailleC brailleCanvas;  TextComponent text;  String curText;  Choice wordSource, whatGrade;  String[] providerNames;  WordProvider[] providers;  Button nextBtn;  volatile boolean inChangeText;    public void init() {        wordSource = new Choice();    whatGrade = new Choice();    whatGrade.add("Grade one braille");    whatGrade.add("Grade two braille");    whatGrade.addItemListener(this);        Panel p, p2;    setLayout(new BorderLayout(10,10));    p = new Panel(new BorderLayout());    p2=new Panel();    p2.add(whatGrade);    p2.add(wordSource);    p.add(p2, "West");    nextBtn = new Button("Next");    p2=new Panel();    p2.add(nextBtn);    p.add(p2, "East");    add(p, "North");    //add(wordSource, "North");    text = new TextArea("", 4, 4, TextArea.SCROLLBARS_VERTICAL_ONLY); //text = new TextField();    add(text, "South");    brailleCanvas = new BrailleC();    add(brailleCanvas);    //wordSource.add("Third Nephi");    wordSource.addItemListener(this);    text.addTextListener(this);    text.addKeyListener(this); // to trap untrapped textValueChanged events...    nextBtn.addActionListener(this);    nextBtn.addKeyListener(this);    this.addKeyListener(this);    wordSource.addKeyListener(this);    String start = getParameter("start text");    if (start == null) start = "Type here.";    setText(start);    text.setText(start+"\n\n\n\n\n");      Thread t = new Thread(this);    t.setPriority(Thread.MIN_PRIORITY);    t.start();      }    public void start() {    text.selectAll();  }    public void run() {    String sourceString = getParameter("word sources");    if (sourceString != null) {      StringTokenizer st = new StringTokenizer(sourceString, ",");      providers = new WordProvider[st.countTokens()];      providerNames = new String[st.countTokens()];      for(int i=0; i<providerNames.length; i++) {        providerNames[i] = st.nextToken().trim();        wordSource.add("Loading...");        System.out.println("Loading "+providerNames[i]);        showStatus("Loading "+providerNames[i]);        providers[i] = getProvider(providerNames[i]);        wordSource.remove("Loading...");        wordSource.add(providerNames[i]);        wordSource.setSize(wordSource.getPreferredSize());        //System.out.println(providerNames[i]);      }      System.out.println("Done");      showStatus("Done");    }    else {      providerNames = new String[1];      providerNames[0] = "User Input";    }  }    public WordProvider getProvider(String source) {    if (source == null || source.equals("User Input")) return null;    String sourceParam = getParameter(source);    if (sourceParam == null) return new ConstantWordProvider("Couldn't find "+source+".");    else if (sourceParam.startsWith("num") || sourceParam.startsWith("Num")) {      try {        if (sourceParam.indexOf(' ') != -1) throw new NumberFormatException("Number doesn't exist.");        return new IntegerWordProvider(Integer.parseInt(sourceParam.substring(sourceParam.indexOf(' ')+1)));      } catch (NumberFormatException e) { return new IntegerWordProvider(1000); }    }    else if (sourceParam.startsWith("money") || sourceParam.startsWith("Money")) {      try {        if (sourceParam.indexOf(' ') != -1) throw new NumberFormatException("Number doesn't exist.");        return new MoneyWordProvider(Integer.parseInt(sourceParam.substring(sourceParam.indexOf(' ')+1)));      } catch (NumberFormatException e) { return new MoneyWordProvider(10); }    }    else if (sourceParam.equalsIgnoreCase("time")) {      return new TimeWordProvider();    }    Vector wordsVector = new Vector();    try {      if (sourceParam.equalsIgnoreCase("choose file")) {        Component fr = this;        while (!(fr instanceof Frame) && fr!=null) fr = fr.getParent();        if (fr==null) fr = new Frame();        FileDialog fd = new FileDialog((Frame)fr, "Import text from what file?");        fd.show();        sourceParam = "file:/"+new File(fd.getDirectory(), fd.getName());      }      InputStream in=(new URL(getDocumentBase(), sourceParam)).openStream();      if (in==null) throw new IOException();      in = new BufferedInputStream(in);      StringBuffer sb=new StringBuffer();      int i=in.read();      while(i != -1) {        if ( Character.isWhitespace((char)i) && i != ' ') {          if (sb.length() != 0) {            wordsVector.addElement(sb.toString());            sb=new StringBuffer();          }        }        else sb.append((char)i);        i=in.read();      }      if (sb.length() != 0) wordsVector.addElement(sb.toString());    }    catch (IOException e) {      System.out.println(e);      StringTokenizer st=new StringTokenizer(sourceParam+" "+e.toString(), " \t,\n\r");      while(st.hasMoreTokens()) wordsVector.addElement(st.nextToken());    }    String[] words = new String[wordsVector.size()];    for(int i=0; i<wordsVector.size(); i++)      words[i] = (String)wordsVector.elementAt(i);    boolean sequential=Character.isUpperCase(words[0].charAt(0)); // uppercase    if (sequential) return new SequentialWordProvider(words);    else return new RandomWordProvider(words);  }      public void setText(String s) {    curText = s.trim()+" ";    brailleCanvas.curBrailleText = getBraille(curText);    brailleCanvas.repaint();  }    public String getBraille(String s) {    try {      ByteArrayOutputStream out = new ByteArrayOutputStream(s.length()*2);      BrailleOutputStream bOut;      if (whatGrade.getSelectedIndex() == 0) bOut = new BrailleOutputStream(out);      else bOut = new Braille2OutputStream(out);      bOut.write(s.getBytes());      bOut.flush();      return out.toString();    } catch (Exception e) { return e.toString(); }  }    public void actionPerformed(ActionEvent e) {    if (e.getSource() == nextBtn) {      setText(nextWord());      text.setText("");      text.selectAll();      text.requestFocus();    }  }    public void textValueChanged(TextEvent e) {    if (inChangeText) return;    inChangeText = true;    if (e.getSource() == text) {      if (wordSource.getSelectedItem()==null);      else if (wordSource.getSelectedItem().equals("User Input")) {        setText(text.getText());      }      else {              String userText = text.getText();        int i;        for(i=0; i<Math.min(userText.length(), curText.length()); i++) {          if (userText.charAt(i) != curText.charAt(i)) break;        }        if (i<userText.length() || i<curText.length()) {          if ( i< userText.length()                  && ( userText.charAt(i) == '?'                       || (i==curText .length()-1 && userText.charAt(i) == '\n')                      || (i==curText .length()-1 && userText.charAt(i) == '\r') )  ) {            if (i<curText.length()) {              userText = userText.substring(0,i)+curText.charAt(i);              try {                text.setText(userText);              }              catch (java.lang.IllegalStateException ex) { System.out.println(ex); }              i++;            }            else {              try {                setText(nextWord());                text.setText("");              }              catch (java.lang.IllegalStateException ex) { System.out.println(ex); }              text.selectAll();            }          }          text.select(i, 1000);          //try { Thread.sleep(1000); } catch (Exception ex) { }        }        else {          try {            setText(nextWord());            text.setText("");          }          catch (java.lang.IllegalStateException ex) { System.out.println(ex); }          text.selectAll();        }      }    }    inChangeText = false;  }    public void keyTyped(KeyEvent e) {     if (e.getSource() != text) text.requestFocus();    else {      textValueChanged(new TextEvent(text, TextEvent.TEXT_VALUE_CHANGED)); // shouldn't have to do this...    }  }  public void keyPressed(KeyEvent e) {}  public void keyReleased(KeyEvent e) {}    public String nextWord() {    if (providers[wordSource.getSelectedIndex()]!=null)       return providers[wordSource.getSelectedIndex()].nextWord();    else return null;  }    public void itemStateChanged(ItemEvent e) {    if (e.getSource() == wordSource) setText(nextWord());    else setText(curText);  }    public Insets getInsets() {    return new Insets(5,5,5,5);  }    class BrailleC extends Canvas {    String curBrailleText;    public void paint(Graphics g) {      brailler.draw(curBrailleText, new Rectangle(0,0,getSize().width, getSize().height), g);    }  }    }abstract class WordProvider {  public abstract String nextWord();}class SequentialWordProvider extends WordProvider {  String[] words;  int i=-1;  public SequentialWordProvider(String[] words) { this.words = words; }  public SequentialWordProvider(String wordString)   {    StringTokenizer st = new StringTokenizer(wordString);    words = new String[st.countTokens()];    int i=0;    while(st.hasMoreTokens()) words[i++] = st.nextToken();    i=-1;  }  public String nextWord() { i = (i+1)%words.length; return words[i]; }}class RandomWordProvider extends WordProvider {  String[] words;  public RandomWordProvider(String[] words) { this.words = words; }  public String nextWord() { return words[(int)(words.length*Math.random())]; }}class IntegerWordProvider extends WordProvider {  int max;  public IntegerWordProvider(int max) { this.max = max; }  public String nextWord() { return ""+(int)(Math.random()*max); }}class TimeWordProvider extends WordProvider {  public String nextWord() { return ""+(int)(12*Math.random())+":"+(int)(10*Math.random())+""+(int)(10*Math.random()); }}class MoneyWordProvider extends WordProvider {  int max;  public MoneyWordProvider(int max) { this.max = max; }  public String nextWord() { return "$"+(int)(max*Math.random())+"."+(int)(10*Math.random())+""+(int)(10*Math.random()); }}class MetaWordProvider extends WordProvider {  WordProvider[] providers;  public MetaWordProvider(WordProvider[] providers) { this.providers = providers; }  public String nextWord() { return providers[(int)(providers.length*Math.random())].nextWord(); }}class ConstantWordProvider extends WordProvider {  String text;  public ConstantWordProvider(String text) { this.text = text; }  public String nextWord() { return text; }}