import java.awt.*; import java.awt.event.*; import java.io.IOException; import java.net.*; import java.util.*; import javax.swing.JPanel; public class UniPaper extends JPanel { private Set _inkPoints; private UniDraw _draw; public UniPaper(UniDraw aUniDraw) { _draw = aUniDraw; _inkPoints = Collections.synchronizedSet(new HashSet()); // Since regular HashSet isn't threadsafe PointInputReader pir = new PointInputReader(); pir.start(); setBackground(Color.WHITE); addMouseListener(new L1()); addMouseMotionListener(new L2()); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.black); //Iterators must be synced synchronized(_inkPoints) { Iterator i = _inkPoints.iterator(); while(i.hasNext()) { Point p = (Point)i.next(); g.fillOval(p.x, p.y, 3, 3); } } } private void addPoint(Point p) { _inkPoints.add(p); repaint(); } /** * Converts a point into string then into bytes and send it to host and port. * Format of string is: point.x + " " + point.y * @param aPoint The point to send * @param aHost remote host * @param aPort remote port */ private void sendPoint(Point aPoint) { String pointAsString = Integer.toString(aPoint.x) + " " + Integer.toString(aPoint.y); byte[] pointMsg = pointAsString.getBytes(); InetAddress iaHost = _draw.getRemoteHost(); int port = _draw.getRemotePort(); try { DatagramPacket dp = new DatagramPacket(pointMsg, pointMsg.length, iaHost, port); DatagramSocket ds = new DatagramSocket(); ds.send(dp); } catch (Exception e) { System.err.println(e); } } class PointInputReader extends Thread { @Override public void run() { try { DatagramSocket ds = new DatagramSocket(_draw.getLocalPort()); byte[] buffer = new byte[65507]; // Max packet size allowed DatagramPacket dp = new DatagramPacket(buffer, buffer.length); while(true) { try { ds.receive(dp); String message = new String(dp.getData(), 0, dp.getLength()); String[] xy = message.split(" "); UniPaper.this.addPoint(new Point(Integer.parseInt(xy[0]), Integer.parseInt(xy[1]))); dp.setLength(65507); // Reset buffer since receive shrinks the buffer. } catch (IOException e) { System.err.println(e); } } } catch (SocketException e) { System.err.println(e); } } } private void addThenSendPoint(Point p) { addPoint(p); sendPoint(p); } class L1 extends MouseAdapter { public void mousePressed(MouseEvent e) { addThenSendPoint(e.getPoint()); } } class L2 extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) { addThenSendPoint(e.getPoint()); } } }