Swing JFC Java

/* From http://java.sun.com/docs/books/tutorial/index.html */
/*
 * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * -Redistribution of source code must retain the above copyright notice, this
 *  list of conditions and the following disclaimer.
 *
 * -Redistribution in binary form must reproduce the above copyright notice,
 *  this list of conditions and the following disclaimer in the documentation
 *  and/or other materials provided with the distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed, licensed or intended
 * for use in the design, construction, operation or maintenance of any
 * nuclear facility.
 */
/*
 * 1.1 version.
 */
import java.io.*;
import java.net.*;
import java.util.*;
class TalkServerThread extends Thread {
    public Socket socket;
    public BufferedReader is;
    public BufferedWriter os;
    TalkServer server;
    boolean DEBUG = false;
    public String toString() {
        return "TalkServerThread: socket = " + socket
               + "; is = " + is
               + "; os = " + os;
    }
    TalkServerThread(Socket socket, TalkServer server) throws IOException {
        super("TalkServer");
        is = new BufferedReader(
     new InputStreamReader(socket.getInputStream()));
        os = new BufferedWriter(
     new OutputStreamWriter(socket.getOutputStream()));
        if (is == null) {
            System.err.println("TalkServerThread: Input stream seemed "
                               + "to be created successfully, but it's null.");
            throw new IOException();
        }
        if (os == null) {
            System.err.println("TalkServerThread: Output stream seemed "
                               + "to be created successfully, but it's null.");
            throw new IOException();
        }
        this.socket = socket;
        this.server = server;
    }
    public void run() {
        while (socket != null) {
            try {
                //Read data.
                String str = is.readLine();
                //Pass it on.
                if (str != null) {
                    server.forwardString(str, this);
                }
            } catch (EOFException e) { //No more data on this socket...
                server.forwardString("SERVER SAYS other applet disconnected",
                                     this);
                cleanup();
                return;
            } catch (NullPointerException e) { //Socket doesn't exist...
                server.forwardString("SERVER SAYS no socket to other applet",
                                     this);
                cleanup();
                return;
            } catch (IOException e) { //Read problem..
                server.forwardString("SERVER SAYS socket trouble with other applet",
                                     this);
                cleanup();
                return;
            } catch (Exception e) { //Unknown exception. Complain and quit.
                System.err.println("Exception on is.readLine():");
                e.printStackTrace();
                cleanup();
                return;
            }
        }
    }
    protected void finalize() {
        cleanup();
    }
    void cleanup() {
        try {
            if (is != null) {
                is.close();
                is = null;
            }
        } catch (Exception e) {} //Ignore errors.
        try {
            if (os != null) {
                os.close();
                os = null;
            }
        } catch (Exception e) {} //Ignore errors.
        try {
            if (socket != null) {
                socket.close();
                socket = null;
            }
        } catch (Exception e) {} //Ignore errors.
    }
}
/*
 * 1.1 version.
 */
import java.net.*;
import java.io.*;
class TalkServer {
    TalkServerThread[] tstList = new TalkServerThread[2];
    boolean DEBUG = false;
    public static void main(String[] args) {
        new TalkServer().start();
    }
    public void start() {
        ServerSocket serverRSocket = null;
        int numConnected = 0;
        try {
            serverRSocket = new ServerSocket(0);
            System.out.println("TalkServer listening on rendezvous port: "
                               + serverRSocket.getLocalPort());
        } catch (IOException e) {
            System.err.println("Server could not create server socket for rendezvous.");
            return;
        }
        while (true) {
            //Connect to two clients.
            while (numConnected < 2) {
                TalkServerThread tst;
                tst = connectToClient(serverRSocket);
                if (tst != null) {
                    numConnected++;
                    if (tstList[0] == null) {
                        tstList[0] = tst;
                    } else {
                        tstList[1] = tst;
                    }
                }
            } //end while (numConnected < 2) loop
            if (DEBUG) {
                try {
                    System.out.println("tst #0 = " + tstList[0]);
                } catch (Exception e) {}
                try {
                    System.out.println("tst #1 = " + tstList[1]);
                } catch (Exception e) {}
            }
            //If they're really OK, tell them to start writing.
            if (everythingIsOK(0) & everythingIsOK(1)) {
                for (int i = 0; i < 2; i++) {
                    writeToStream("START WRITING!\n----------------------"
                                  + "-------------", tstList[i].os);
                }
            } else {
                System.err.println("2 server threads created, but "
                                   + "not everything is OK");
            }
            while (numConnected == 2) {
                if (!everythingIsOK(0)) {
                    if (DEBUG) {
                        System.out.println("Applet #0 is hosed; disconnecting.");
                    }
                    numConnected--;
                    cleanup(tstList[0]);
                    tstList[0] = null;
                }
                if (!everythingIsOK(1)) {
                    if (DEBUG) {
                        System.out.println("Applet #1 is hosed; disconnecting.");
                    }
                    numConnected--;
                    cleanup(tstList[1]);
                    tstList[1] = null;
                }
                       try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                } 
            } //end while(numConnected==2) loop
            if (DEBUG) {
                try {
                    System.out.println("Number of connections = " + numConnected);
                    System.out.println("tst #0 = " + tstList[0]);
                    System.out.println("tst #1 = " + tstList[1]);
                } catch (Exception e) {}
            }
        } //end while (true) loop
    }
    protected TalkServerThread connectToClient(ServerSocket serverRSocket) {
        Socket rendezvousSocket = null;
        TalkServerThread tst = null;
        //Listen for client connection on the rendezvous socket.
        try {
            rendezvousSocket = serverRSocket.accept();
        } catch (IOException e) {
            System.err.println("Accept failed.");
            e.printStackTrace();
            return null;
        }
        //Create a thread to handle this connection.
        try {
            tst = new TalkServerThread(rendezvousSocket, this);
            tst.start();
        } catch (Exception e) {
             System.err.println("Couldn't create TalkServerThread:");
            e.printStackTrace();
            return null;
        }
        writeToStream("Successful connection. "
                      + "Please wait for second applet to connect...",
                      tst.os);
        return tst;
    }
    boolean everythingIsOK(int tstNum) {
        TalkServerThread tst = tstList[tstNum];
        if (tst == null) {
            if (DEBUG) {
                System.out.println("TalkServerThread #" + tstNum
                                   + " is null");
            }
            return false;
        } else {
            if (tst.os == null) {
                if (DEBUG) {
                    System.out.println("TalkServerThread #" + tstNum
                                       + " output stream is null.");
                }
                return false;
            }
            if (tst.is == null) {
                if (DEBUG) {
                    System.out.println("TalkServerThread #" + tstNum
                                       + " input stream is null.");
                }
                return false;
            }
            if (tst.socket == null) {
                if (DEBUG) {
                    System.out.println("TalkServerThread #" + tstNum
                                       + " socket is null.");
                }
                return false;
            }
        }
        return true;
    }
    void cleanup(TalkServerThread tst) {
        if (tst != null) {
            try {
                if (tst.os != null) {
                    tst.os.close();
                    tst.os = null;
                }
            } catch (Exception e) {} //Ignore errors
            try {
                if (tst.is != null) {
                    tst.is.close();
                    tst.is = null;
                }
            } catch (Exception e) {} //Ignore errors
            try {
                if (tst.socket != null) {
                    tst.socket.close();
                    tst.socket = null;
                }
            } catch (Exception e) {} //Ignore errors
        }
    }
    public void forwardString(String string, TalkServerThread requestor) {
        BufferedWriter clientStream = null;
        if (tstList[0] == requestor) {
            if (tstList[1] != null) {
                clientStream = tstList[1].os;
            } else {
                if (DEBUG) {
                    System.out.println("Applet #0 has a string to forward, "
                                       + "but Applet #1 is gone...");
                }
                return;
            }
        } else {
            if (tstList[0] != null) {
                clientStream = tstList[0].os;
            } else {
                if (DEBUG) {
                    System.out.println("Applet #1 has a string to forward, "
                                       + "but Applet #0 is gone...");
                }
                return;
            }
        }
        if (clientStream != null) {
            writeToStream(string, clientStream);   
        } else if (DEBUG) {
            System.out.println("Can't forward string -- no output stream.");
        }
    }
    public void writeToStream(String string, BufferedWriter stream) {
        if (DEBUG) {
            System.out.println("TalkServer about to forward data: "
                               + string);
        }
        try { 
            stream.write(string);
      stream.newLine();
            stream.flush();
            if (DEBUG) {
                System.out.println("TalkServer forwarded string.");
            }
        } catch (IOException e) {
            System.err.println("TalkServer failed to forward string:");
            e.printStackTrace();
            return;
        } catch (NullPointerException e) {
            System.err.println("TalkServer can't forward string "
                               + "since output stream is null.");
            return;
        }
    }
}
/*
 * 1.1 version.
 */
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class TalkClientApplet extends Applet 
              implements Runnable,
             ActionListener {
    Socket socket;
    BufferedWriter os;
    BufferedReader is;
    TextField portField, message;
    TextArea display;
    Button button;
    int dataPort;
    boolean trysted;
    Thread receiveThread;
    String host;
    boolean DEBUG = false;
    String newline;
    public void init() {
        //Get the address of the host we came from.
        host = getCodeBase().getHost();
        //Set up the UI.
        GridBagLayout gridBag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        setLayout(gridBag);
        message = new TextField("");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridwidth = GridBagConstraints.REMAINDER;
        gridBag.setConstraints(message, c); 
  message.addActionListener(this);
        add(message);
        display = new TextArea(10, 40);
        display.setEditable(false);
        c.weightx = 1.0;
        c.weighty = 1.0;
        c.fill = GridBagConstraints.BOTH;
        gridBag.setConstraints(display, c); 
        add(display);
        Label l = new Label("Enter the port (on host " + host
                            + ") to send the request to:", 
                            Label.RIGHT);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridwidth = 1;
        c.weightx = 0.0;
        c.weighty = 0.0;
        gridBag.setConstraints(l, c); 
        add(l);
        portField = new TextField(6);
        c.fill = GridBagConstraints.NONE;
        gridBag.setConstraints(portField, c); 
  portField.addActionListener(this);
        add(portField);
        button = new Button("Connect");
        gridBag.setConstraints(button, c); 
  button.addActionListener(this);
        add(button);
  newline = System.getProperty("line.separator");
    }
    public synchronized void start() {
        if (DEBUG) {
            System.out.println("In start() method.");
        }
        if (receiveThread == null) {
            trysted = false;
            portField.setEditable(true);
            button.setEnabled(true);
            os = null;
            is = null;
            socket = null;
            receiveThread = new Thread(this);
            receiveThread.start();
            if (DEBUG) {
                System.out.println("  Just set everything to null and started thread.");
            }
        } else if (DEBUG) {
            System.out.println("  receiveThread not null! Did nothing!");
        }
    }
    public synchronized void stop() {
        if (DEBUG) {
            System.out.println("In stop() method.");
        }
        receiveThread = null;
        trysted = false;
        portField.setEditable(true);
        button.setEnabled(true);
        notify();
        try { //Close input stream.
            if (is != null) {
                is.close();
                is = null;
            }
        } catch (Exception e) {} //Ignore exceptions.
        try { //Close output stream.
            if (os != null) {
                os.close();
                os = null;
            }
        } catch (Exception e) {} //Ignore exceptions.
        try { //Close socket.
            if (socket != null) {
                socket.close();
                socket = null;
            }
        } catch (Exception e) {} //Ignore exceptions.
    }
            
    public Insets getInsets() {
        return new Insets(4,4,5,5);
    }
    public void paint(Graphics g) {
        Dimension d = getSize();
        Color bg = getBackground();
        g.setColor(bg);
        g.draw3DRect(0, 0, d.width - 1, d.height - 1, true);
        g.draw3DRect(3, 3, d.width - 7, d.height - 7, false);
    }
    public synchronized void actionPerformed(ActionEvent event) {
        int port;
        
        if (DEBUG) {
            System.out.println("In action() method.");
        }
        if (receiveThread == null) {
            start();
        }
        if (!trysted) {
        //We need to attempt a rendezvous.
            if (DEBUG) {
                System.out.println("  trysted = false. "
                                   + "About to attempt a rendezvous.");
            }
            //Get the port the user entered...
            try {
                port = Integer.parseInt(portField.getText());
            } catch (NumberFormatException e) {
                //No integer entered. 
                display.append("Please enter an integer below."
             + newline);
                return;
            }
            //...and rendezvous with it.
            rendezvous(port);
        } else { //We've already rendezvoused. Just send data over.
            if (DEBUG) {
                System.out.println("  trysted = true. "
                                   + "About to send data.");
            }
            String str = message.getText();
            message.selectAll();
            try {
                os.write(str);
    os.newLine();
                os.flush();
            } catch (IOException e) {
                display.append("ERROR: Applet couldn't write to socket."
             + newline);
                display.append("...Disconnecting."
             + newline);
                stop();
                return;
            } catch (NullPointerException e) {
                display.append("ERROR: No output stream!"
             + newline);
                display.append("...Disconnecting."
             + newline);
                stop();
                return;
            }
            display.append("Sent: " + str + newline);
        }
    }
    synchronized void waitForTryst() {
        //Wait for notify() call from action().
        try {
            wait();        
        } catch (InterruptedException e) {}
        if (DEBUG) {
            System.out.println("waitForTryst about to return. "
                               + "trysted = " + trysted + ".");
        }
        return;
    }
    public void run() {
        String received = null;
        waitForTryst();
        //OK, now we can send messages.
        while (Thread.currentThread() == receiveThread) {
            try { 
                //Wait for data from the server.
                received = is.readLine();
                //Display it.
                if (received != null) {
                    display.append("Received: " + received 
           + newline);
                } else { //success but no data...
                    System.err.println("End of stream?");
        return; //XXX
                }
            } catch (IOException e) { //Perhaps a temporary problem?
                display.append("NOTE: Couldn't read from socket.\n");
                return;
            }
        }
    }
    private void rendezvous(int port) {
        //Try to open a socket to the port.
        try {
            socket = new Socket(host, port);
        } catch (UnknownHostException e) {
            display.append("ERROR: Can't find host: " + host
         + newline);
            return;
        } catch (IOException e) {
            display.append("ERROR: Can't open socket on rendezvous port "
                           + port + " (on host " + host + ")."
         + newline);
            return;
        }
        //Try to open streams to read and write from the socket.
        try {
            os = new BufferedWriter(
         new OutputStreamWriter(socket.getOutputStream()));
            is = new BufferedReader(
         new InputStreamReader(socket.getInputStream()));
        } catch (IOException e) {
            display.append("ERROR: Created data socket but can't "
                           + "open stream on it."
         + newline);
            display.append("...Disconnecting." + newline);
            stop();
            return;
        }   
        if ((os != null) & (is != null)) {
            if (DEBUG) {
                System.out.println("Successful rendezvous.");
                System.out.println("socket = " + socket);
                System.out.println("output stream = " + os);
                System.out.println("input stream = " + is);
            }
            //Let the main applet thread know we've successfully rendezvoused.
            portField.setEditable(false);
            button.setEnabled(false);
            trysted = true;
            notify();
        } else {
            display.append("ERROR: Port is valid but communication failed. "
                           + "Please TRY AGAIN." + newline);
        }
    }
}