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; } }