Newer
Older
ServerTester / src / main / java / info / istlab / ServerTester / WhiteBoardClient.java
package info.istlab.ServerTester;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class WhiteBoardClient extends JPanel implements MouseListener, MouseMotionListener, Runnable {
    private static final long serialVersionUID = 1L;
    // private static final int PORT = 11111;
    // private static final String ADDRESS = "127.0.0.1";
    JFrame frame;
    ArrayList<Point> tmpStroke = new ArrayList<Point>();
    CopyOnWriteArrayList<String> points = new CopyOnWriteArrayList<String>();
    Socket socket = null;
    BufferedReader reader = null;
    PrintWriter writer = null;
    Thread thread;
    int lastx, lasty;

    public WhiteBoardClient(int port, String address) {
        address = address.replace("/", "");

        try {
            socket = new Socket();
            socket.connect(new InetSocketAddress(address, port), 1000); // 1秒でタイムアウト
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer = new PrintWriter(socket.getOutputStream(), true);
        } catch (Exception e) {
            System.err.println("サーバ [" + address + ":" + port + "] に接続できませんでした");
            System.exit(1); // 異常終了(エラーで終了)なら1
        }

        addMouseListener(this);
        addMouseMotionListener(this);
        frame = new JFrame("WhiteBoard Client " + socket.toString());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 400);
        frame.add(this);
        frame.setVisible(true);

        System.out.println("Client socket info: " + socket.toString());

        thread = new Thread(this);
        thread.start();

        new RepaintClient(this);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (e.getX() == lastx && e.getY() == lasty) {
            return;
        }
        tmpStroke.add(e.getPoint());
        lastx = e.getX();
        lasty = e.getY();
        repaint();
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        tmpStroke = new ArrayList<Point>();
        tmpStroke.add(e.getPoint());
        lastx = e.getX();
        lasty = e.getY();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // tmpStroke.add(e.getPoint());
        int[][] pts = new int[tmpStroke.size()][2];
        for (int i = 0; i < tmpStroke.size(); i++) {
            pts[i][0] = tmpStroke.get(i).x;
            pts[i][1] = tmpStroke.get(i).y;
        }
        String msg = MyJSON.toJSON(pts);
        points.add(msg);
        repaint();

        // ここでサーバにメッセージを送信
        writer.println(msg);
        writer.flush();
        System.out.println("sent: " + msg.length());
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    synchronized public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Iterator<String> it = points.iterator();
        while (it.hasNext()) {
            int[][] points = MyJSON.fromJSON(it.next());
            for (int[] p : points) {
                int x = p[0];
                int y = p[1];
                g.fillOval(x, y, 3, 3);
            }
        }
    }

    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("Usage: java WhiteBoardClient <port> <address>");
            System.exit(1);
        }
        int port = Integer.parseInt(args[0]);
        String address = args[1];
        new WhiteBoardClient(port, address);
    }

    @Override
    public void run() {
        // データを受け取る
        while (thread != null) {
            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    points.add(line);
                    System.out.println("received: " + line.length());
                }
                repaint();
            } catch (IOException e1) {
                e1.printStackTrace();
                thread = null;
                if (e1 instanceof SocketException) {
                    System.err.println("サーバとの接続が切れました (Connection reset)");
                }
            }
        }
    }
}

/**
 * 上記のrun()において、メッセージを送信しないと reader.readLine() で止まってしまって画面描画されないので、
 * 1秒ごとに強制的に再描画するためのスレッド
 */
class RepaintClient implements Runnable {
    private WhiteBoardClient client;
    Thread thread;

    public RepaintClient(WhiteBoardClient client) {
        this.client = client;
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while (true) {
            client.repaint();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class MyJSON {
    // convert int[][] to JSON
    public static String toJSON(int[][] points) {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        for (int i = 0; i < points.length; i++) {
            sb.append("[");
            sb.append(points[i][0]);
            sb.append(",");
            sb.append(points[i][1]);
            sb.append("]");
            if (i < points.length - 1) {
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }

    // convert JSON to int[][]
    public static int[][] fromJSON(String json) {
        json = json.substring(2, json.length() - 2).replaceAll("\\],\\[", "_");
        String[] points = json.split("_");
        int[][] pts = new int[points.length][2];
        for (int i = 0; i < points.length; i++) {
            // System.out.println(points[i]);
            String[] xy = points[i].replaceAll("\\[", "").split(",");
            pts[i][0] = Integer.parseInt(xy[0]);
            pts[i][1] = Integer.parseInt(xy[1]);
        }
        return pts;
    }
}