プログラム (Java)

//
//      曖昧検索サーバにJavaからアクセス
//
import java.awt.*;
import java.applet.Applet;
import java.net.*;
import java.io.*;

public class Word15 extends Applet {
        PitecanCanvas pc;
        DynamicTextField dtf;
        Searcher searcher;
        String host;

        public void init(){
                host = getDocumentBase().getHost();
                searcher = new Searcher(host,5555);
                pc = new PitecanCanvas(searcher,host);
                dtf = new DynamicTextField(searcher,pc);
                setLayout(new BorderLayout());
                add("North",dtf);
                add("Center",pc);
        }
}

class J2U {  // ユニコード変換クラス
        private static String uc[] = {
        "\u3000\u3001\u3002\uff0c\uff0e\u30fb\uff1a\uff1b\uff1f\uff01\u309b\u309c"+
        "\u00b4\uff40\u00a8\uff3e\uffe3\uff3f\u30fd\u30fe\u309d\u309e\u3003\u4edd"+
        ...
        };
        static String convert(String s){
        ...
        }
}

class Searcher extends Object { // 曖昧検索サーバと通信して検索を行なう
        Socket socket;
        DataInputStream in;
        DataOutputStream out;
        int nmatch;
        String matchedWords[];
        String contents[];
        boolean connected;

        public Searcher(String server, int port){
                try {
                        socket = new Socket(server, port);
                        in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
                        out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
                        connected = true;
                } catch (IOException e) {
                        connected = false;
                }
        }
        int search(int ambig, String pat){
                if(! connected) return -1;
                try {
                        out.writeBytes("S"+String.valueOf(ambig)+pat+" \n");
                        out.flush();
                        nmatch = Integer.parseInt(in.readLine().trim());
                        matchedWords = new String[nmatch];
                        contents = new String[nmatch];
                        return nmatch;
                } catch (IOException e) {
                        System.out.println("Search Failed!");
                        return -1;
                }
        }

        void getEntry(int start, int end, int step){ // 一度に複数の侯補エントリを取得
                String s;
                if(! connected) return;
                try {
                        int i,se;
                        out.writeBytes("E"+String.valueOf(start)+
                                        ","+String.valueOf(end)+
                                        ","+String.valueOf(step)+"\n");
                        out.flush();
                        while(true){
                                s = in.readLine();
                                if(s.length() > 0) break;
                        }
                        for(i=start;(se = s.indexOf(9)) > 0;i+=step){
                                matchedWords[i] = s.substring(0,se);
                                s = s.substring(se+1);
                        }
                }catch (IOException e) {
                        System.err.println("Can't get word entries");
                }
        }

        String getContent(int index){
                String s;
                if(! connected) return "";
                try {
                        out.writeBytes("C"+String.valueOf(index)+"\n");
                        out.flush();
                        return in.readLine().trim();
                } catch (IOException e) {
                        System.err.println("Can't get a word content");
                        return "";
                }
        }
        void getContent(int start, int end, int step){
                String s;
                if(! connected) return;
                try {
                        int i,se;
                        out.writeBytes("C"+String.valueOf(start)+
                                        ","+String.valueOf(end)+
                                        ","+String.valueOf(step)+"\n");
                        out.flush();
                        while(true){
                                s = in.readLine();
                                if(s.length() > 0) break;
                        }
                        for(i=start;(se = s.indexOf(9)) > 0;i+=step){
                                contents[i] = s.substring(0,se);
                                s = s.substring(se+1);
                        }
                }catch (IOException e) {
                        System.err.println("Can't get word entries");
                }
        }
}

class DynamicTextField extends TextField { // キー入力の度に検索/表示を行なうためのTextFieldのサブクラス
        Searcher searcher;
        PitecanCanvas pitecanCanvas;
        String searchText = "";

        public DynamicTextField(Searcher s, PitecanCanvas pc){
                setFont(new Font("Helvetica",Font.PLAIN,18));
                searcher = s;
                pitecanCanvas = pc;
                searcher.search(0,"");
                pitecanCanvas.reset();
        }

        public void search(){
                String s;
                s = getText();
                if(s.compareTo(searchText) != 0){
                        int n;
                        searchText = s;
                        for(int ambig=0; ambig<=4; ambig++){
                                n = searcher.search(ambig,searchText);
                                if(n > 0) break;
                        }
                        pitecanCanvas.reset();
                }
        }
        public boolean keyUp(Event e, int key) {
                search();
                return false; // 上にイベントをわたす
        }
        public Dimension minimumSize() {
                return new Dimension(300,40);
        }
        public Dimension preferredSize() {
                return minimumSize();
        }
}

class PitecanCanvas extends Canvas { // 侯補表示キャンバス
        Searcher searcher;
        Font efont, cfont;
        Color blue, black, bgcolor;
        String host;

        public PitecanCanvas(Searcher s, String h){
                searcher = s;
                host = h;
                efont = new Font("Helvetica",Font.PLAIN,18);
                cfont = new Font("Helvetica",Font.PLAIN,16);
                blue = new Color(0x0000ff);
                black = new Color(0x000000);
                bgcolor = new Color(0xffffdd);
                reset();
        }
        public void reset(){
                repaint();
        }
        public void paint(Graphics g){
                String s;
                int i,n;

                g.setColor(bgcolor);
                g.fillRect(0,0,500,500);

                if(! searcher.connected){
                        g.setFont(efont);
                        g.setColor(blue);
                        g.drawString("Sorry! Dictionary server is not running on ``" +
                                host + "''.",10,30);
                        g.drawString("Please send e-mail to masui@csl.sony.co.jp, and",10,60);
                        g.drawString("tell him about the problem. Thank you.",10,80);
                }

                n = (10 > searcher.nmatch ? searcher.nmatch : 10);

                g.setFont(efont);
                g.setColor(blue);
                searcher.getEntry(0,n-1,1);
                for(i=0; i<n; i++){
                        g.drawString(searcher.matchedWords[i],10,i*38+20);
                }
                g.setFont(cfont);
                g.setColor(black);
                searcher.getContent(0,n-1,1);
                for(i=0; i<n; i++){
                        s = J2U.convert(searcher.contents[i]);
                        g.drawString(s,40,i*38+40);
                }
        }
        public Dimension minimumSize() {
                return new Dimension(450,500);
        }
        public Dimension preferredSize() {
                return minimumSize();
        }
}