_A Text UI for the Java AWT_
by Stuart D. Gathman

Listing One
class SomeClass {
  static void main(String args[]) {
 Properties props = System.getProperties();
 props.put("awt.toolkit","bmsi.tui.TUIKit");
  }
import java.awt.*;
class TUIFrame extends Frame {
  public Toolkit getToolkit() {
 return new bmsi.tui.Toolkit();
  }
}

Listing Two
class TUIColorModel extends java.awt.image {
  static int getGrayLevel(Color c) {
 int red = c.getRed();
 int blue = c.getBlue();
 int green = c.getGreen();
 return (red + blue + blue + green) / 4;
  }
  static int getTextPixel(Color c) {
 int gray = getGrayLevel(c);
 if (gray < 32) return 0;
 if (gray < 192) return 1;
 return 2;
  }
}

Listing Three
class TUIKit extends java.awt.Toolkit {
  private TUIColorModel colorModel = new TUIColorModel();
  private String[] fontlist = { "Terminal" };

  public ColorModel getColorModel() { return colorModel; }
  public String[] getFontList() { return fontlist; }
  public FontMetrics getFontMetrics(Font f) {
 return new TUIFontMetrics(f);
  }
}

Listing Four
class TUITextComponent extends TUIComponent
  implements TextComponentPeer {
  private String txt;
  void setText(String s) {
 txt = s;   // keep a local copy
 toolkit.writeCmd(this,SETTEXT,s);
  }
}

Listing Five
interface RemotePeer {
  /** execute a command from our remote partner */
  void remoteMethod(int cmd) throws IOException;
  /** return the object id our remote partner knows us by. */
  int getID();
  /** return the java.awt Component or MenuComponent for this
   peer. */
  Object getTarget();
}

Listing Six
class TUIKit extends Toolkit implements RemotePeer {
  private Vector objs;
  private DataInput in;
  /** wait for an input event from our remote client. */
  private void readCmd() {
 try {
   flush();
   int id = in.readShort();
   int cmd = in.readShort();
   RemotePeer peer = (RemotePeer)objs.elementAt(id);
   peer.remoteMethod(cmd);
 }
 catch (IOException e) {
   throw new AWTError(e.toString());
  }
 }
}


Listing Seven
class TUIKit extends Toolkit implements Runnable, RemotePeer {
  public void run() {
 try {
   for (;;)
     readCmd();
 }
 // remote client has gone away
 catch (AWTError e) {
   debug(e);
   // exit if loaded via inetd
   if (server == null)
     System.exit(0);
  }
 }
}

Listing Eight
class TUIKit extends Toolkit implements RemotePeer {
  protected TextFieldPeer createTextField(TextField t) {
 return new TUITextField(t,this);
  }
}

Listing Nine
class TUIKit extends Toolkit implements RemotePeer {
  synchronized int createRemotePeer(RemotePeer par,
  int type,RemotePeer peer) {
 if (par == null)
   par = this;
 /* Vector won't search for null, so we search for ourselves
 knowing that a real TUIKit reference will be in pos 0 only */
 int id = objs.indexOf(this,1);
 if (id < 0) {
   id = objs.size();
   objs.addElement(peer);
 }
 else
   objs.setElementAt(peer,id);
 writeCmd(par,type,id);
 return id;
  }
  void removePeer(int id) {
 if (id < 0) return;
 objs.setElementAt(this,id);
 writeCmd(id,DISPOSE);
  }
}

Listing Ten
class TUIKit {
  EventQueue theQueue = new EventQueue;
  protected EventQueue getSystemEventQueueImpl() {
 return theQueue;
  }
}

Listing Eleven
class TUIKit extends Toolkit implements RemotePeer {
  flushTarget = new TUISync(this);
  synchronized void writeCmd(RemotePeer peer,int cmd) {
 writeCmd(peer.getID(),cmd);
 if (!needFlush) {
   needFlush = true;
   flushTarget.queue();
  }
 }
}

Listing Twelve
class TUIComponent implements ComponentPeer, RemotePeer {
  protected Component target;
  protected TUIKit toolkit;
  protected int winID = -1;
  protected TUIComponent(Component comp,TUIKit toolkit) {
 this.toolkit = toolkit;
 target = comp;
 Container parent = target.getParent();
 TUIContainer parentpeer = null;
 if (parent != null)
   parentpeer = (TUIContainer)parent.getPeer();
 create(parentpeer);   // create our remote partner, set winID
 initialize();         // copy target state to remote partner
  }
}

Listing Thirteen
class TUIButton extends TUIComponent implements ButtonPeer {
  TUIButton(Button but,TUIKit toolkit) { super(but,toolkit); }
  protected void create(TUIContainer parent) {
 winID = toolkit.createRemotePeer(parent,NEWBUTTON,this);
  }
  public Dimension getMinimumSize() {
 Button but = (Button)target;
 return new Dimension(but.getLabel().length(),1);
  }
  protected void initialize() {
 Button but = (Button)target;
 String text = but.getLabel();
 if (text != null)
   setLabel(text);
 super.initialize();
  }
  public void setLabel(String s) {
 toolkit.writeCmd(winID,SETTEXT,s);
  }
  public void remoteMethod(int cmd) throws IOException {
 if (cmd == MENUPICK) {
   Button but = (Button)target;
   toolkit.theQueue.postEvent(
     new ActionEvent(but,
       ActionEvent.ACTION_PERFORMED,but.getActionCommand()
     )
   );
   return;
 }
 super.remoteMethod(cmd);
}

Listing Fourteen
class TUICheckbox extends TUIComponent implements CheckboxPeer {
  public void remoteMethod(int cmd) throws IOException {
 if (cmd == MENUPICK) {
   Checkbox cb = (Checkbox)target;
   boolean flag = !cb.getState();
   cb.setState(flag);
   toolkit.theQueue.postEvent(
     new ItemEvent(cb,
       ItemEvent.ITEM_STATE_CHANGED,cb.getLabel(),
       flag ? ItemEvent.SELECTED : ItemEvent.DESELECTED
     )
   );
   return;
 }
 super.remoteMethod(cmd);
 }
}

Listing Fifteen
class TUIGraphics extends Graphics {
  private TUIKit toolkit;
  private TUIComponent target;
  private Color color;
  private Font font;
  private Rectangle clipRect;
  private int posx, posy;
  private boolean XORmode;
}

Listing Sixteen
class TUIGraphics extends Graphics {
  private RemotePeer getID() {
 if (target.currentGraphics != this) {
   toolkit.writeCmd(target,INITGRAPHICS);
   target.currentGraphics = this;
   if (font != null)
     setFont(font);
   // Should XORmode affect color?
   if (color != null)
     setColor(color);
   if (clipRect != null)
     setClip(clipRect);
   if (posx != 0 || posy != 0)
     translate(0,0);
  }
 return target;
 }
}

Listing Seventeen
class TUIGraphics extends Graphics {
  public void setClip(Shape s) {
 clipRect = s.getBounds();
 if (target.currentGraphics == this)
   toolkit.writeCmd(target,CLIPRECT,
     clipRect.x,clipRect.y,clipRect.width,clipRect.height);
  }
}




