first commit
This commit is contained in:
167
CS2335/lab4/Lab_files/Examples/Graphics/BasicGraphics.java
Normal file
167
CS2335/lab4/Lab_files/Examples/Graphics/BasicGraphics.java
Normal file
@@ -0,0 +1,167 @@
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.Container;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* CS2335 Lab 6 Example
|
||||
*
|
||||
* <PRE>
|
||||
* BasicGrpahics.java shows the basics of how to draw simple objects
|
||||
* <PRE>
|
||||
*
|
||||
* @author <A HREF="mailto:tedchoc@cc.gatech.edu">Ted Choc</A>
|
||||
* @version Version 1.4, February 20, 2003
|
||||
*/
|
||||
public class BasicGraphics {
|
||||
/**
|
||||
* JFrame to which everything is rendered
|
||||
*/
|
||||
private JFrame guiFrame;
|
||||
|
||||
/**
|
||||
* Content Pane of the JFrame
|
||||
*/
|
||||
private Container contentPane;
|
||||
|
||||
/**
|
||||
* The panel to which all the graphics will be drawn
|
||||
*/
|
||||
private JPanel graphicsPanel;
|
||||
|
||||
/**
|
||||
* A modifier for guiFrame
|
||||
* @param guiFrame new guiFrame
|
||||
*/
|
||||
public void setGuiFrame(JFrame guiFrame) {
|
||||
this.guiFrame = guiFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* A modifier for contentPane
|
||||
* @param contentPane new contentPane
|
||||
*/
|
||||
public void setContentPane(Container contentPane) {
|
||||
this.contentPane = contentPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* A modifier for graphicsPanel
|
||||
* @param graphicsPanel new graphicsPanel
|
||||
*/
|
||||
public void setGraphicsPanel(JPanel graphicsPanel) {
|
||||
this.graphicsPanel = graphicsPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* An accessor for guiFrame
|
||||
* @return JFrame guiFrame
|
||||
*/
|
||||
public JFrame getGuiFrame() {
|
||||
return this.guiFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* An accessor for contentPane
|
||||
* @return Container contentPane
|
||||
*/
|
||||
public Container getContentPane() {
|
||||
return this.contentPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* An accessor for graphicsPanel
|
||||
* @return JPanel graphicsPanel
|
||||
*/
|
||||
public JPanel getGraphicsPanel() {
|
||||
return this.graphicsPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the window and sets it up for drawing
|
||||
*/
|
||||
public void makeWindow() {
|
||||
guiFrame = new JFrame("Basic Graphics Objects");
|
||||
|
||||
/* Handle Closing the Window */
|
||||
guiFrame.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent we) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
contentPane = guiFrame.getContentPane();
|
||||
graphicsPanel = new JPanel() {
|
||||
/* Overwrite JPanels paintComponent Method */
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
drawGraphics(g);
|
||||
}
|
||||
};
|
||||
contentPane.add(graphicsPanel);
|
||||
guiFrame.setSize(175, 240);
|
||||
guiFrame.setVisible(true);
|
||||
graphicsPanel.setBackground(Color.lightGray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that draws the Graphics onto the graphicsPanel
|
||||
* @param g graphics g object
|
||||
*/
|
||||
public void drawGraphics(Graphics g) {
|
||||
/* Draws some Text */
|
||||
g.setColor(Color.black);
|
||||
g.drawString("Hey look, I'm some Text", 15, 15);
|
||||
|
||||
/* Draws a fancy 3-D Rectangle */
|
||||
g.setColor(Color.red);
|
||||
g.fill3DRect(50, 50, 50, 50, true);
|
||||
g.setColor(Color.blue);
|
||||
g.fillRect(60, 60, 30, 30);
|
||||
|
||||
/* Draws a line */
|
||||
g.setColor(Color.yellow);
|
||||
g.drawLine(50, 120, 130, 140);
|
||||
|
||||
/* Draws a circle */
|
||||
g.setColor(Color.orange);
|
||||
g.fillOval(140, 60, 20, 20);
|
||||
|
||||
/* Draws Complex Shape :) */
|
||||
g.setColor(Color.red);
|
||||
g.fillRoundRect(67, 145, 105, 30, 25, 25);
|
||||
g.fillRoundRect(75, 170, 89, 33, 10, 10);
|
||||
|
||||
g.setColor(Color.white);
|
||||
g.fillOval(72, 150, 18, 18);
|
||||
g.fillOval(147, 150, 18, 18);
|
||||
|
||||
g.setColor(Color.yellow);
|
||||
g.fillOval(84, 180, 6, 6);
|
||||
g.fillOval(147, 180, 6, 6);
|
||||
|
||||
g.setColor(Color.black);
|
||||
g.drawOval(72, 150, 18, 18);
|
||||
g.drawOval(147, 150, 18, 18);
|
||||
g.drawOval(84, 180, 6, 6);
|
||||
g.drawOval(147, 180, 6, 6);
|
||||
g.fillRoundRect(95, 150, 5, 50, 2, 2);
|
||||
g.fillRoundRect(102, 150, 5, 50, 2, 2);
|
||||
g.fillRoundRect(109, 150, 5, 50, 2, 2);
|
||||
g.fillRoundRect(116, 150, 5, 50, 2, 2);
|
||||
g.fillRoundRect(123, 150, 5, 50, 2, 2);
|
||||
g.fillRoundRect(130, 150, 5, 50, 2, 2);
|
||||
g.fillRoundRect(137, 150, 5, 50, 2, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method that creates a new BasicGraphics
|
||||
* @param args Command Line Arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
BasicGraphics test = new BasicGraphics();
|
||||
test.makeWindow();
|
||||
}
|
||||
}
|
||||
288
CS2335/lab4/Lab_files/Examples/Graphics/SimpleAnimation.java
Normal file
288
CS2335/lab4/Lab_files/Examples/Graphics/SimpleAnimation.java
Normal file
@@ -0,0 +1,288 @@
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.Container;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Color;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
/**
|
||||
* CS2335 Lab 6 Example
|
||||
*
|
||||
* <PRE>
|
||||
* SimpleAnimation.java shows the basics of how to create an animation
|
||||
* <PRE>
|
||||
*
|
||||
* @author <A HREF="mailto:tedchoc@cc.gatech.edu">Ted Choc</A>
|
||||
* @version Version 1.4, February 20, 2003
|
||||
*/
|
||||
public class SimpleAnimation {
|
||||
/**
|
||||
* JFrame to which everything is rendered
|
||||
*/
|
||||
private JFrame guiFrame;
|
||||
|
||||
/**
|
||||
* Content Pane of the JFrame
|
||||
*/
|
||||
private Container contentPane;
|
||||
|
||||
/**
|
||||
* The panel to which all the graphics will be drawn
|
||||
*/
|
||||
private JPanel graphicsPanel;
|
||||
|
||||
/**
|
||||
* Determines the current rotation of the polygon
|
||||
*/
|
||||
private int rotationValue = 0;
|
||||
|
||||
/**
|
||||
* Determines how the current polygon should be scaled
|
||||
*/
|
||||
private double scaleValue = 1.0;
|
||||
|
||||
/**
|
||||
* Determines whether to shrink or grow the polygon
|
||||
*/
|
||||
private boolean increasingScale = true;
|
||||
|
||||
/**
|
||||
* Determines what color the square should be
|
||||
* 0 - Red, 1 - Green, 2 - Blue
|
||||
*/
|
||||
private int colorSelection = 0;
|
||||
|
||||
/**
|
||||
* Determines the current color
|
||||
*/
|
||||
private Color currentColor = Color.red;
|
||||
|
||||
/**
|
||||
* A modifier for guiFrame
|
||||
* @param guiFrame new guiFrame
|
||||
*/
|
||||
public void setGuiFrame(JFrame guiFrame) {
|
||||
this.guiFrame = guiFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* A modifier for contentPane
|
||||
* @param contentPane new contentPane
|
||||
*/
|
||||
public void setContentPane(Container contentPane) {
|
||||
this.contentPane = contentPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* A modifier for graphicsPanel
|
||||
* @param graphicsPanel new graphicsPanel
|
||||
*/
|
||||
public void setGraphicsPanel(JPanel graphicsPanel) {
|
||||
this.graphicsPanel = graphicsPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* An accessor for guiFrame
|
||||
* @return JFrame guiFrame
|
||||
*/
|
||||
public JFrame getGuiFrame() {
|
||||
return this.guiFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* An accessor for contentPane
|
||||
* @return Container contentPane
|
||||
*/
|
||||
public Container getContentPane() {
|
||||
return this.contentPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* An accessor for graphicsPanel
|
||||
* @return JPanel graphicsPanel
|
||||
*/
|
||||
public JPanel getGraphicsPanel() {
|
||||
return this.graphicsPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the window and sets it up for drawing
|
||||
*/
|
||||
public void makeWindow() {
|
||||
guiFrame = new JFrame("Simple Animation");
|
||||
guiFrame.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent we) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
contentPane = guiFrame.getContentPane();
|
||||
graphicsPanel = new JPanel() {
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
drawGraphics(g);
|
||||
}
|
||||
};
|
||||
contentPane.add(graphicsPanel);
|
||||
guiFrame.setSize(500, 500);
|
||||
guiFrame.setVisible(true);
|
||||
graphicsPanel.setBackground(Color.lightGray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the polygon on the Graphics
|
||||
* @param g the graphics object to be drawn on
|
||||
*/
|
||||
public void drawGraphics(Graphics g) {
|
||||
int[] xCoord = { 200, 300, 300, 200 };
|
||||
int[] yCoord = { 200, 200, 300, 300 };
|
||||
Polygon rectangle = new Polygon(xCoord, yCoord, 4);
|
||||
|
||||
//g.fillPolygon(rectangle);
|
||||
g.setColor(currentColor);
|
||||
g.fillPolygon(rotatePolygon(scalePolygon(rectangle, scaleValue),
|
||||
rotationValue));
|
||||
|
||||
//g.setColor(Color.blue);
|
||||
//g.fillPolygon(rotatePolygon(rectangle, 60));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the polygon by some angle - look into AffineTransform
|
||||
* for a better way to handle this. This is also kind of a
|
||||
* hack because it only works for rectangles, but it works for
|
||||
* this example
|
||||
* Rotation Matrix
|
||||
* | cos(a) -sin(a) 0 |
|
||||
* | sin(a) cos(a) 0 |
|
||||
* | 0 0 1 |
|
||||
* @param p polygon to be rotated
|
||||
* @param theta the angle to be rotated by
|
||||
* @return Polygon that has been rotated
|
||||
*/
|
||||
public Polygon rotatePolygon(Polygon p, int theta) {
|
||||
int[] xCoord = p.xpoints;
|
||||
int[] yCoord = p.ypoints;
|
||||
int xMidpoint = ((xCoord[1] - xCoord[0]) / 2) + xCoord[0];
|
||||
int yMidpoint = ((yCoord[2] - yCoord[1]) / 2) + yCoord[1];
|
||||
p.translate(-xMidpoint, -yMidpoint);
|
||||
xCoord = p.xpoints;
|
||||
yCoord = p.ypoints;
|
||||
|
||||
int[] xRotCoord = new int[p.xpoints.length];
|
||||
int[] yRotCoord = new int[p.ypoints.length];
|
||||
int numPoints = p.npoints;
|
||||
double thetaRad = Math.toRadians((double) theta);
|
||||
|
||||
for (int i = 0; i < numPoints; i++) {
|
||||
xRotCoord[i] = (int) (xCoord[i] * Math.cos(thetaRad))
|
||||
+ (int) (yCoord[i] * Math.sin(thetaRad));
|
||||
yRotCoord[i] = (int) (-(xCoord[i]) * Math.sin(thetaRad))
|
||||
+ (int) (yCoord[i] * Math.cos(thetaRad));
|
||||
}
|
||||
|
||||
Polygon rotatedP = new Polygon(xRotCoord, yRotCoord, numPoints);
|
||||
rotatedP.translate(xMidpoint, yMidpoint);
|
||||
p.translate(xMidpoint, yMidpoint);
|
||||
|
||||
return rotatedP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales the polygon by the specfied amount
|
||||
* @param p polygon prior to being scaled
|
||||
* @param scalar the amount to shrink or the grow the polygon by
|
||||
* @return the polygon that has been scaled
|
||||
*/
|
||||
public Polygon scalePolygon(Polygon p, double scalar) {
|
||||
int[] xCoord = p.xpoints;
|
||||
int[] yCoord = p.ypoints;
|
||||
int xMidpoint = ((xCoord[1] - xCoord[0]) / 2) + xCoord[0];
|
||||
int yMidpoint = ((yCoord[2] - yCoord[1]) / 2) + yCoord[1];
|
||||
p.translate(-xMidpoint, -yMidpoint);
|
||||
xCoord = p.xpoints;
|
||||
yCoord = p.ypoints;
|
||||
|
||||
int[] xScaleCoord = new int[p.xpoints.length];
|
||||
int[] yScaleCoord = new int[p.ypoints.length];
|
||||
int numPoints = p.npoints;
|
||||
|
||||
for (int i = 0; i < numPoints; i++) {
|
||||
xScaleCoord[i] = (int) (scalar * xCoord[i]);
|
||||
yScaleCoord[i] = (int) (scalar * yCoord[i]);
|
||||
}
|
||||
|
||||
Polygon scaledP = new Polygon(xScaleCoord, yScaleCoord, numPoints);
|
||||
scaledP.translate(xMidpoint, yMidpoint);
|
||||
p.translate(xMidpoint, yMidpoint);
|
||||
|
||||
return scaledP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the square
|
||||
*/
|
||||
public void animateGraphics() {
|
||||
ActionListener listener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
rotationValue = (rotationValue + 5) % 360;
|
||||
|
||||
if (increasingScale == true) {
|
||||
if (scaleValue >= 2.5) {
|
||||
increasingScale = false;
|
||||
} else {
|
||||
scaleValue = scaleValue + 0.05;
|
||||
}
|
||||
} else {
|
||||
if (scaleValue <= 0.5) {
|
||||
increasingScale = true;
|
||||
} else {
|
||||
scaleValue = scaleValue - 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
if (colorSelection == 0) {
|
||||
currentColor = new Color(currentColor.getRed() - 5,
|
||||
currentColor.getGreen() + 5, 0);
|
||||
|
||||
if (currentColor.getRed() <= 0) {
|
||||
colorSelection = 1;
|
||||
}
|
||||
} else if (colorSelection == 1) {
|
||||
currentColor = new Color(0,
|
||||
currentColor.getGreen() - 5,
|
||||
currentColor.getBlue() + 5);
|
||||
|
||||
if (currentColor.getGreen() <= 0) {
|
||||
colorSelection = 2;
|
||||
}
|
||||
} else {
|
||||
currentColor = new Color(currentColor.getRed() + 5, 0,
|
||||
currentColor.getBlue() - 5);
|
||||
|
||||
if (currentColor.getBlue() <= 0) {
|
||||
colorSelection = 0;
|
||||
}
|
||||
}
|
||||
|
||||
graphicsPanel.repaint();
|
||||
}
|
||||
};
|
||||
|
||||
javax.swing.Timer animation = new javax.swing.Timer(50, listener);
|
||||
animation.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SimpleAnimation and begins the animation
|
||||
* @param args Command Line Arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
SimpleAnimation test = new SimpleAnimation();
|
||||
test.makeWindow();
|
||||
test.animateGraphics();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
public abstract class AbstractNetworkMessage implements Serializable {
|
||||
|
||||
//////////////////////////////// Data Members ///////////////////////////////
|
||||
private String messageName;
|
||||
|
||||
//////////////////////////////// Constructors ///////////////////////////////
|
||||
public AbstractNetworkMessage() {
|
||||
messageName = "AbstractMessage";
|
||||
}
|
||||
|
||||
public AbstractNetworkMessage(String name) {
|
||||
messageName = name;
|
||||
}
|
||||
|
||||
////////////////////////////////// Methods //////////////////////////////////
|
||||
|
||||
public String getMessageName() {
|
||||
return messageName;
|
||||
}
|
||||
|
||||
public String tokenize() {
|
||||
return messageName;
|
||||
}
|
||||
|
||||
}// end of class AbstractNetworkMessage
|
||||
32
CS2335/lab4/Lab_files/Examples/Networking/ClientExample.java
Normal file
32
CS2335/lab4/Lab_files/Examples/Networking/ClientExample.java
Normal file
@@ -0,0 +1,32 @@
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
class ClientExample {
|
||||
public static final int PORT = 1234;
|
||||
|
||||
public static void main(String argv[]) {
|
||||
try {
|
||||
Socket s = new Socket("localhost", PORT);
|
||||
BufferedReader br = new BufferedReader(new
|
||||
InputStreamReader(s.getInputStream()));
|
||||
PrintWriter pr = new PrintWriter(new
|
||||
OutputStreamWriter(s.getOutputStream()));
|
||||
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
|
||||
|
||||
System.out.println(s.getLocalAddress().toString());
|
||||
System.out.println(s.getLocalSocketAddress().toString());
|
||||
|
||||
String message = null;
|
||||
|
||||
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
|
||||
|
||||
while((message = stdIn.readLine()) != null) {
|
||||
System.out.println("Sending message: " + message);
|
||||
oos.writeObject(new TextMessage(message));
|
||||
oos.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO Exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
23
CS2335/lab4/Lab_files/Examples/Networking/NumberMessage.java
Normal file
23
CS2335/lab4/Lab_files/Examples/Networking/NumberMessage.java
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
public class NumberMessage extends AbstractNetworkMessage {
|
||||
|
||||
//////////////////////////////// Data Members ///////////////////////////////
|
||||
private int myNumber;
|
||||
|
||||
//////////////////////////////// Constructors ///////////////////////////////
|
||||
/**
|
||||
* Creates a new <code>NumberMessage</code> instance.
|
||||
*
|
||||
*/
|
||||
public NumberMessage(int number) {
|
||||
super("NumberMessage");
|
||||
|
||||
myNumber = number;
|
||||
}
|
||||
|
||||
////////////////////////////////// Methods //////////////////////////////////
|
||||
public String tokenize() {
|
||||
return super.tokenize() + ": " + Integer.toString(myNumber);
|
||||
}
|
||||
|
||||
}// end of class NumberMessage
|
||||
@@ -0,0 +1,24 @@
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
class ClientExample {
|
||||
public static final int PORT = 1234;
|
||||
|
||||
public static void main(String argv[]) {
|
||||
try {
|
||||
Socket s = new Socket("localhost", PORT);
|
||||
BufferedReader br = new BufferedReader(new
|
||||
InputStreamReader(s.getInputStream()));
|
||||
PrintWriter pr = new PrintWriter(new
|
||||
OutputStreamWriter(s.getOutputStream()));
|
||||
|
||||
System.out.println(s.getLocalAddress().toString());
|
||||
System.out.println(s.getLocalSocketAddress().toString());
|
||||
pr.println("Hello, world!");
|
||||
pr.flush();
|
||||
System.out.println(br.readLine());
|
||||
} catch (IOException e) {
|
||||
System.out.println("IO Exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
class ServerExample extends Thread {
|
||||
|
||||
Socket socket;
|
||||
public static final int PORT = 1234;
|
||||
|
||||
public ServerExample(Socket socket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
PrintWriter pr = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
|
||||
|
||||
String s = br.readLine();
|
||||
System.out.println("Received " + s);
|
||||
pr.println("Thank you for your input");
|
||||
pr.flush();
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Got IO Exception: " + ioe.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
try {
|
||||
ServerSocket ss = new ServerSocket(PORT);
|
||||
while (true) {
|
||||
Socket s = ss.accept();
|
||||
new ServerExample(s).start();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Got IO Exception: " + ioe.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
45
CS2335/lab4/Lab_files/Examples/Networking/ServerExample.java
Normal file
45
CS2335/lab4/Lab_files/Examples/Networking/ServerExample.java
Normal file
@@ -0,0 +1,45 @@
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
class ServerExample extends Thread {
|
||||
|
||||
Socket socket;
|
||||
public static final int PORT = 1234;
|
||||
|
||||
public ServerExample(Socket socket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
PrintWriter pr = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
|
||||
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
|
||||
AbstractNetworkMessage anm;
|
||||
|
||||
while((anm = ((AbstractNetworkMessage)(ois.readObject()))) != null) {
|
||||
String s = anm.tokenize();
|
||||
System.out.println("Received " + s);
|
||||
pr.println("Thank you for your input");
|
||||
pr.flush();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Got IO Exception: " + ioe.getMessage());
|
||||
} catch(Exception e) {
|
||||
System.out.println("Something aint workin': " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
try {
|
||||
ServerSocket ss = new ServerSocket(PORT);
|
||||
while (true) {
|
||||
Socket s = ss.accept();
|
||||
new ServerExample(s).start();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Got IO Exception: " + ioe.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
19
CS2335/lab4/Lab_files/Examples/Networking/TextMessage.java
Normal file
19
CS2335/lab4/Lab_files/Examples/Networking/TextMessage.java
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
public class TextMessage extends AbstractNetworkMessage {
|
||||
|
||||
//////////////////////////////// Data Members ///////////////////////////////
|
||||
private String myMessage;
|
||||
|
||||
//////////////////////////////// Constructors ///////////////////////////////
|
||||
public TextMessage(String msg) {
|
||||
super("TextMessage");
|
||||
|
||||
myMessage = msg;
|
||||
}
|
||||
|
||||
////////////////////////////////// Methods //////////////////////////////////
|
||||
public String tokenize() {
|
||||
return super.tokenize() + ": " + myMessage;
|
||||
}
|
||||
|
||||
}// end of class TextMessage
|
||||
@@ -0,0 +1,25 @@
|
||||
import java.util.*;
|
||||
|
||||
class ThreadExample extends Thread {
|
||||
String s;
|
||||
Random r;
|
||||
public ThreadExample(String s) {
|
||||
this.s = s;
|
||||
this.r = new Random();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for(int i=0; i<5; i++) {
|
||||
System.out.println(s);
|
||||
try {
|
||||
this.sleep(r.nextInt(100));
|
||||
} catch (InterruptedException e)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
new ThreadExample("String One").start();
|
||||
new ThreadExample("String Two").start();
|
||||
}
|
||||
}
|
||||
60
CS2335/lab4/Lab_files/Examples/Threading/SimpleThread.java
Normal file
60
CS2335/lab4/Lab_files/Examples/Threading/SimpleThread.java
Normal file
@@ -0,0 +1,60 @@
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class SimpleThread implements Runnable {
|
||||
|
||||
private boolean terminate;
|
||||
|
||||
public SimpleThread() {
|
||||
// super("Sleepy Thread");
|
||||
|
||||
terminate = true;
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return !terminate;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
terminate = false;
|
||||
|
||||
while(!terminate) {
|
||||
System.out.println("SimpleThread is alive!");
|
||||
// try {
|
||||
// this.sleep(2000);
|
||||
// } catch(InterruptedException ie) {
|
||||
// System.out.println("SimpleThread's sleep was interrupted!");
|
||||
// break;
|
||||
// }
|
||||
for(int i=1; i<2000000; i+=2) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("\nSimpleThread is dead...");
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
terminate = true;
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
SimpleThread st = new SimpleThread();
|
||||
new Thread(st).start();
|
||||
|
||||
String input = null;
|
||||
BufferedReader stdIn=new BufferedReader(new InputStreamReader(System.in));
|
||||
|
||||
try {
|
||||
while((input = stdIn.readLine()) != null) {
|
||||
if(input.equals("Kill")) {
|
||||
st.kill();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(IOException ioe) {
|
||||
System.err.println("Caught IO Exception: " + ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}// end of class SimpleThread
|
||||
25
CS2335/lab4/Lab_files/Examples/Threading/ThreadExample.java
Normal file
25
CS2335/lab4/Lab_files/Examples/Threading/ThreadExample.java
Normal file
@@ -0,0 +1,25 @@
|
||||
import java.util.*;
|
||||
|
||||
class ThreadExample extends Thread {
|
||||
String s;
|
||||
Random r;
|
||||
public ThreadExample(String s) {
|
||||
this.s = s;
|
||||
this.r = new Random();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for(int i=0; i<5; i++) {
|
||||
System.out.println(s);
|
||||
try {
|
||||
this.sleep(r.nextInt(100));
|
||||
} catch (InterruptedException e)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
new ThreadExample("String One").start();
|
||||
new ThreadExample("String Two").start();
|
||||
}
|
||||
}
|
||||
607
CS2335/lab4/Lab_files/lab4.html
Normal file
607
CS2335/lab4/Lab_files/lab4.html
Normal file
@@ -0,0 +1,607 @@
|
||||
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>Chapter<EFBFBD>4.<2E>
|
||||
NetPaint -- A networked paint program.
|
||||
</title><link rel="stylesheet" href="http://www.cc.gatech.edu/classes/AY2003/cs2335_spring/labs/style.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.59.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter" lang="en"><div class="titlepage"><div><h2 class="title"><a name="id2783850"></a>Chapter<EFBFBD>4.<2E>
|
||||
NetPaint -- A networked paint program.
|
||||
</h2></div><div><div class="author"><h3 class="author">Joseph Czechowski</h3></div></div><div><div class="author"><h3 class="author">Ted Choc</h3></div></div><div><div class="author"><h3 class="author">Adrian Abraham</h3></div></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="3"><b>Revision History</b></th></tr><tr><td align="left">Revision 1.0</td><td align="left">2004.01.16</td><td align="left">JC4</td></tr><tr><td align="left" colspan="3">Initial drafting of the lab, importing of parts of tools
|
||||
section from previous semesters.</td></tr></table></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#id2785975">1. Overview of NetPaint</a></dt><dt><a href="#id2785992">2. Tools</a></dt><dd><dl><dt><a href="#id2786000">2.1. UI's In Java</a></dt><dt><a href="#id2786446">2.2. Threading In Java</a></dt><dt><a href="#id2786573">2.3. Introduction to Networking</a></dt></dl></dd><dt><a href="#id2786731">3. Project Requirements</a></dt><dd><dl><dt><a href="#id2786738">3.1. Overview</a></dt><dt><a href="#id2786755">3.2. Networking</a></dt><dt><a href="#id2786838">3.3. Draw Tools</a></dt><dt><a href="#id2787098">3.4. Other Required Features</a></dt></dl></dd><dt><a href="#id2787274">4. Suggested Design</a></dt><dd><dl><dt><a href="#id2787280"></a></dt></dl></dd><dt><a href="#id2787680">5. Deliverables</a></dt><dd><dl><dt><a href="#id2787698">5.1. Deliverables for Part 1</a></dt><dt><a href="#id2787792">5.2. Deliverables for Part 2</a></dt><dt><a href="#id2787868">5.3. Deliverables for Part 3</a></dt></dl></dd><dt><a href="#id2787914">6. Extra Credit</a></dt></dl></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="http://www.cc.gatech.edu/classes/AY2003/cs2335_spring/labs/images/important.png"></td><th align="left">Important</th></tr><tr><td colspan="2" align="left" valign="top"><p>
|
||||
<span class="bold"><b>Part 1</b></span>
|
||||
is due on WebCT before 2004.01.30 08:00:00 (A.M.)!
|
||||
</p><p>
|
||||
<span class="bold"><b>Part 2</b></span>
|
||||
is due on WebCT before 2004.02.06 08:00:00 (A.M.)!
|
||||
</p><p>
|
||||
<span class="bold"><b>Part 3</b></span>
|
||||
is due on WebCT before 2004.02.13 08:00:00 (A.M.)!
|
||||
</p><p>
|
||||
***DO NOT WAIT UNTIL THE LAST MINUTE TO SUBMIT YOUR ASSIGNMENT!!!***
|
||||
</p></td></tr></table></div><div class="section" lang="en"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2785975"></a>1. Overview of NetPaint</h2></div></div><p>
|
||||
Everyone is familiar with the basic paint programs that are typically
|
||||
bundled with their favorite/least-favorite OS. NetPaint is similar to
|
||||
those programs, but with the (obvious) added twist that it is networked.
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2785992"></a>2. Tools</h2></div></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2786000"></a>2.1. UI's In Java</h3></div></div><div class="section" lang="en"><div class="titlepage"><div><h4 class="title"><a name="id2786007"></a>2.1.1. Introduction</h4></div></div><p>
|
||||
In the past, you have had experience using Swing components to
|
||||
develop Graphical User Interfaces (GUIs). This lab will expand
|
||||
these skills and give you the ability to create customized
|
||||
graphics by using the Graphics[2D] class. By the end of the lab,
|
||||
you will have created a simple paint program using these new GUI
|
||||
creation skills.
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h4 class="title"><a name="id2785940"></a>2.1.2. Introduction to Graphics</h4></div></div><p>
|
||||
In Java, manipulation of Graphics objects is not a particularly
|
||||
difficult task. Since the Graphics class is abstract, you cannot
|
||||
directly create one by calling its constructor. You must instead
|
||||
obtain them from previously defined Graphics objects or by
|
||||
calling the getGraphics() method on a
|
||||
Component(java.awt.Component) or any of its subclasses. Before
|
||||
you call the getGraphics() method on a component, it must be
|
||||
displayable (i.e. the [J]Frame to which the component is added
|
||||
must be visible - [J]Frame.setVisible(true)). Once you have a
|
||||
Graphics object, you can begin to manipulate it. Graphics
|
||||
objects have methods used to draw basic shapes, such as
|
||||
characters, strings, polygons, but anything more complex will
|
||||
require you to combine shapes to achieve the desired output.
|
||||
Look at the Java API (java.awt.Graphics) for the exact commands
|
||||
necessary to do this. Unfortunately, accessing graphics in this
|
||||
manner causes some problems (mainly every time the window is
|
||||
changed - minimized, resized, overlapped by another window,
|
||||
etc... - the graphic you just made will be erased). To correct
|
||||
this problem, you need to override the paintComponent() method
|
||||
in the Component whose Graphic you wish to access. This method
|
||||
is called every time the window needs to be redrawn, so by doing
|
||||
all of your Graphics changes in this method you will fix the
|
||||
aforementioned problem of losing your Graphic.
|
||||
</p><p>
|
||||
The Graphics2D class in Java allows for more flexibility when
|
||||
rendering Graphical Objects (Graphics objects can be cast to
|
||||
Graphics2D objects). Check out this
|
||||
<a href="http://java.sun.com/docs/books/tutorial/2d/index.html" target="_top">
|
||||
Graphics2D tutorial
|
||||
</a>
|
||||
for more information on this subject. Other sections of the Java
|
||||
tutorial may be of additional assistance.
|
||||
</p><p>
|
||||
We've provided a simple Graphics example, BasicGraphics.java,
|
||||
that shows you what can be done with basic calls to a Graphics
|
||||
object.
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h4 class="title"><a name="id2786273"></a>2.1.3. Introduction to Animation</h4></div></div><p>
|
||||
Although you will not be required to animate anything in this lab,
|
||||
it might be helpful to look over this section for help in future
|
||||
labs (wink, wink).
|
||||
</p><p>
|
||||
Making something animated is as simple as creating a Timer that
|
||||
periodically repaints the components to be animated.Java
|
||||
implements a Timer(javax.swing.Timer) to be used in animations.
|
||||
A Timer requires an actionListener and a delay. After you call
|
||||
start() on the Timer, the actionListener will be called every
|
||||
"delay" milliseconds. The actionListener will make the changes
|
||||
necessary to create the next frame and then call repaint on the
|
||||
component, which actually renders it.
|
||||
</p><p>
|
||||
Drawing straight to the screen is a bad idea - it looks really
|
||||
bad, since the individual objects will be drawn to the screen in
|
||||
a delayed fashion, instead of all at once. To avoid this problem,
|
||||
a technique called double buffering comes into play. Double
|
||||
buffering is a method that renders the next image to be displayed
|
||||
in an off-screen buffer and then swaps it with the current image
|
||||
(do a search on Google for double buffering in Java for some good
|
||||
examples). However, thanks to the helpful people at sun, if you
|
||||
use Swing Components, double buffering is done for you.
|
||||
</p><p>
|
||||
We've also provided you with an Animation example,
|
||||
<a href="SimpleAnimation.java" target="_top">SimpleAnimation.java</a>.
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h4 class="title"><a name="id2786332"></a>2.1.4. Graphics Optimizations</h4></div></div><p>
|
||||
Since its nearly impossible to get the complete desired graphical
|
||||
effects and animations by simply using Graphics2D, images often
|
||||
need to come into play. While there are numerous image subclasses,
|
||||
and practically infinite combination of ways to load them, for the
|
||||
sake of simplicity and speed its recommended to use BufferedImages.
|
||||
A BufferedImage can be drawn from a Graphics(2D) object's
|
||||
drawImage(...) methods, the tricky part is efficiently loading an
|
||||
image.
|
||||
</p><p>
|
||||
To load a BufferedImage from a file, the class you should be
|
||||
interested in is javax.imageio.ImageIO and more specifically the
|
||||
read(URL ...) method You'll notice the method is static, so there
|
||||
is no need to init the class and can simply be used as such below:
|
||||
</p><p>
|
||||
<span class="bold"><b>BufferedImage</b></span> toLoad =
|
||||
<span class="bold"><b>javax.imageio.ImageIO.read(
|
||||
getClass().getResource("myImage.png"));
|
||||
</b></span>
|
||||
</p><p>
|
||||
The getClass().getResource(...) method calls are simply a way to
|
||||
return a URL from path, referenced from the current classes location.
|
||||
The read(...) method used as such above, well return a fully loaded
|
||||
BufferedImage, meaning that you will NOT have worry about using
|
||||
something such as the MediaTracker to ensure the image is ready to
|
||||
be drawn.
|
||||
</p><p>
|
||||
If after using BufferedImages, you find your frame-rate is still being
|
||||
hindered, you can attempt to pass off some of the work to the graphics
|
||||
card by making the images hardware accelerated.
|
||||
</p><pre class="screen">
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
public class ImageLoader
|
||||
{
|
||||
final GraphicsConfiguration gc;
|
||||
|
||||
public ImageLoader(GraphicsConfiguration gc)
|
||||
{
|
||||
if(gc==null)
|
||||
{
|
||||
gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
|
||||
}
|
||||
this.gc = gc;
|
||||
}
|
||||
|
||||
public BufferedImage loadImage(String resource)
|
||||
{
|
||||
try
|
||||
{
|
||||
BufferedImage src = javax.imageio.ImageIO.read(getClass().getResource(resource));
|
||||
BufferedImage dst = gc.createCompatibleImage(src.getWidth(),src.getHeight(),src.getColorModel().getTransparency());
|
||||
Graphics2D g2d = dst.createGraphics();
|
||||
g2d.setComposite(AlphaComposite.Src);
|
||||
g2d.drawImage(src,0,0,null);
|
||||
g2d.dispose();
|
||||
return dst;
|
||||
}
|
||||
catch(java.io.IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre><p>
|
||||
With a class similar to above, using the loadImage(...) method will
|
||||
return a fully accelerated BufferedImage ready to be rendered. If
|
||||
you look more carefully at the loadImage(...) method you should
|
||||
already see concepts that are/will be familiar to you. A
|
||||
BufferedImage has Graphics2D object that can be directly drawn upon
|
||||
just like any other rendering surface. The loadImage(...) method
|
||||
simply loads an image through the method explained above, then
|
||||
creates another "blank" BufferedImage with acceleration, and then
|
||||
proceeds to draw the first image onto the second. If desired, you
|
||||
could add further code below the g2d.drawImage(...) to draw
|
||||
lines/text/etc that would be permanently stored upon the image.
|
||||
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2786446"></a>2.2. Threading In Java</h3></div></div><div class="section" lang="en"><div class="titlepage"><div><h4 class="title"><a name="id2786454"></a>2.2.1. Introduction</h4></div></div><p>
|
||||
Threads allow multiple concurrent paths of execution. In Java,
|
||||
there are different ways to create a new thread:
|
||||
</p><div class="orderedlist"><ol type="A"><li>Implement the Runnable interface, and pass an instance
|
||||
of the class to the Thread constructor, or</li><li>Extend Thread</li></ol></div><p>
|
||||
</p><p>
|
||||
When running on a machine with multiple processors, multiple
|
||||
threads can actually run at the same time. Under normal
|
||||
circumstances, on uniprocessor machines, the threads are time-shared,
|
||||
rapidly switching back and forth, simulating concurrent execution.
|
||||
</p><p>
|
||||
A class which is going to run as its own thread needs to have a
|
||||
method called run declared as public and void, with no
|
||||
arguments. When the thread is started with start(), run will be
|
||||
called and will run separately from the rest of the program.
|
||||
</p><p>
|
||||
We've provided an extremely simple threaded example called
|
||||
ThreadExample.java.
|
||||
</p><p>
|
||||
If you try this out, you'll see that "String One" and "String Two"
|
||||
will be printed on the console in some random order, since both
|
||||
threads are running at once and sleeping random amounts between
|
||||
messages.
|
||||
</p><p>
|
||||
Threads are important in a wide variety of applications. One of
|
||||
their most important applications is networking. Traditional
|
||||
networking makes heavy use of threads, because traditional
|
||||
networking uses blocking I/O. In other words, when you call a
|
||||
function, it doesn't return until it's finished. When you wait for a
|
||||
client to connect, you can't continue until you receive a
|
||||
connection. When you want to read from a connection, you can't
|
||||
continue until you've filled your buffer. When you write to a
|
||||
socket, you can't continue until all of the data has been
|
||||
written. Without threads, it would be nearly impossible to do
|
||||
anything useful since you would always be waiting on one client,
|
||||
unable to handle all the others.
|
||||
</p><p>
|
||||
This is where threads come in. On the server end, each client will
|
||||
get its own thread. That way, the blocking operations each block in
|
||||
their own threads, without affecting any of the other threads. On
|
||||
the client end, each client-server and client-client connection gets
|
||||
its own thread. In addition, the user interface gets its own thread,
|
||||
so that the user can interact with the program even when all of the
|
||||
network connections are blocking.
|
||||
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2786573"></a>2.3. Introduction to Networking</h3></div></div><p>
|
||||
In Java, networking is fairly simple. On the server end, the server
|
||||
creates a ServerSocket. This socket repeatedly accept()s, getting
|
||||
a Socket back from each call and spawning a thread to handle each
|
||||
new Socket.
|
||||
</p><p>
|
||||
On the client end, it's even easier. Just create a socket and
|
||||
connect() it to a listening server.
|
||||
</p><p>
|
||||
The most useful Socket functions are getInputStream() and
|
||||
getOutputStream(). By wrapping these streams in other IO classes
|
||||
(such as PrintWriter and BufferedReader), you can do all of the
|
||||
reading and writing you'll ever need.
|
||||
</p><p>
|
||||
We've provided you with a simple client and server pair, to see
|
||||
what a threaded networking program looks like. These are the
|
||||
ClientExample.java and ServerExample.java.
|
||||
</p><p>
|
||||
<span class="bold"><b>Server</b></span>
|
||||
</p><div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc">Create a Server</li><li style="list-style-type: disc">Bind to a port</li><li style="list-style-type: disc">Wait for client connections (accept)</li><li style="list-style-type: disc">When a new connection comes in, get the socket and create
|
||||
and start a new thread to communicate with the client. Be
|
||||
sure to properly terminate the thread when you're done
|
||||
with it!</li><li style="list-style-type: disc">Meanwhile, go back and wait for another connection
|
||||
request.</li><li style="list-style-type: disc">When the server exits, close server socket and gracefully
|
||||
shut down all threads.</li></ul></div><p>
|
||||
</p><p>
|
||||
<span class="bold"><b>Client</b></span>
|
||||
</p><div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc">Create a networking thread and connect to server.
|
||||
</li><li style="list-style-type: disc">Send/Recv Messages.</li><li style="list-style-type: disc">If you receive a client-to-client connection request,
|
||||
spawn a new thread and create a new socket to handle
|
||||
that.</li><li style="list-style-type: disc">Close Connection.</li></ul></div><p>
|
||||
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="http://www.cc.gatech.edu/classes/AY2003/cs2335_spring/labs/images/note.png"></td><th align="left">Note</th></tr><tr><td colspan="2" align="left" valign="top"><p>
|
||||
Connection to the server must be threaded - otherwise,
|
||||
interaction with the UI will not be possible.
|
||||
</p></td></tr></table></div><p>
|
||||
</p><p>
|
||||
Here is a link to Java's Networking Tutorial:
|
||||
<a href="http://java.sun.com/docs/books/tutorial/networking/index.html" target="_top">
|
||||
http://java.sun.com/docs/books/tutorial/networking/index.html</a>
|
||||
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2786731"></a>3. Project Requirements</h2></div></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2786738"></a>3.1. Overview</h3></div></div><p>
|
||||
NetPaint is a networked paint program where two users may interact
|
||||
with a single drawing canvas. Here both users can see the image and
|
||||
both can interact with it (e.g. drawing new parts of the image).
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2786755"></a>3.2. Networking</h3></div></div><p>
|
||||
Before programming you team should define a protocol that will be
|
||||
used throughout the project. This will keep the confusion to a
|
||||
minimum. There are many, many different ways to define a protocol,
|
||||
but here is a simple one that should give you an idea of how to do
|
||||
it. Also for the most part, your server will be broadcasting all of
|
||||
the messages directly to all of the clients without any modification.
|
||||
</p><pre class="screen">
|
||||
-------------- Initial Sign-on ---------------
|
||||
> HELO: [username]
|
||||
|
||||
------------ Send a chat message ------------
|
||||
> CHAT: [username]:TEXT
|
||||
|
||||
--------------- Draw a line -----------------
|
||||
> LINE: [username]:StartX,StartY:EndX,EndY:RGB Color
|
||||
|
||||
------------- Draw a Rectangle --------------
|
||||
> RECT: [username]:StartX,StartY:Height:Width:RGB Color:Fill (Y/N)
|
||||
|
||||
-------------- Undo previous step -----------
|
||||
> UNDO: [username]
|
||||
|
||||
----------------- Sign-off ------------------
|
||||
> QUIT: [username]
|
||||
|
||||
Also note that by using the above protocol, you need to prevent users
|
||||
from using a ':' in their username. This protocol was done as an example,
|
||||
and does not represent the best solution or a complete one.
|
||||
</pre><p>
|
||||
</p><p>
|
||||
Your server must support at least 5 simultaneous clients, which means that
|
||||
the server must be multi-threaded. Also, the server must prevent two users
|
||||
from specifying the same username. All of the networking in this lab must
|
||||
be handled by using TCP Sockets, which are described very well in Java's networking
|
||||
tutorial (linked in section 2.3).
|
||||
</p><p>
|
||||
<span class="bold"><b>Special Note:</b></span>
|
||||
Your team must determine a method for handling the "ordering of
|
||||
events." This means that it is your choice as to how "simultaneous
|
||||
events" (occurring on the two systems) are handled. You may select
|
||||
an "absolute ordering" of events which prevents inconsistencies
|
||||
between what each user sees **OR** you may select to use "receive
|
||||
ordering" where each system processes the event in the order it
|
||||
is received this is probably the easiest to implement but may
|
||||
result in minor inconsistencies between what each of the users
|
||||
sees.
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2786838"></a>3.3. Draw Tools</h3></div></div><p>
|
||||
NetPaint should be able to do the following:
|
||||
</p><div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc"><span class="bold"><b>Draw Shapes:</b></span>
|
||||
The user should be able to draw:
|
||||
<div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc">Rectangles
|
||||
<span class="emphasis"><em>(See java.awt.Rectangle)</em></span></li><li style="list-style-type: disc">Polygons (made up of several points)
|
||||
<span class="emphasis"><em>(See java.awt.Polygon)</em></span></li><li style="list-style-type: disc">Triangles (a polygon of three points)
|
||||
<span class="emphasis"><em>(See java.awt.Polygon)</em></span></li><li style="list-style-type: disc">Lines
|
||||
<span class="emphasis"><em>(See java.awt.geom.Line2D)</em></span></li><li style="list-style-type: disc">Quadratic Curves
|
||||
<span class="emphasis"><em>(See java.awt.geom.QuadCurve2D)</em></span></li><li style="list-style-type: disc">Ellipses
|
||||
<span class="emphasis"><em>(See java.awt.geom.Ellipse2D)</em></span></li></ul></div>
|
||||
Except for the lines and curves all of the above should be able
|
||||
to be inserted in "filled" or "un-filled" form (it is your team's
|
||||
option whether or not the "filled" versions have a border or
|
||||
not). Additionally the user should be able to choose the color
|
||||
of the item to be inserted
|
||||
<span class="emphasis"><em>(See javax.swing.JColorChooser,
|
||||
javax.swing.colorchooser.AbstractColorChooserPanel)</em></span>
|
||||
and pick the appropriate control points.
|
||||
</li><li style="list-style-type: disc"><span class="bold"><b>Insert Images:</b></span>
|
||||
Users should be able to select an image to load from their system
|
||||
and insert into the picture. Additionally, the user should be able
|
||||
to select the position of insertion and the insertion size.
|
||||
(Your team may decide to allow only scaling of the image where
|
||||
the X:Y ratio is maintained or your team may decide to permit
|
||||
resizing where the image's ratio is not maintained.)
|
||||
<span class="emphasis"><em>(See javax.swing.ImageIcon)</em></span><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="http://www.cc.gatech.edu/classes/AY2003/cs2335_spring/labs/images/note.png"></td><th align="left">Note</th></tr><tr><td colspan="2" align="left" valign="top"><p>
|
||||
You are only required to support the use of images that are
|
||||
available via the internet <span class="emphasis"><em>(See
|
||||
javax.swing.ImageIcon(java.net.URL))</em></span> and will require you
|
||||
to transfer only the text of the URL (e.g.
|
||||
"http://www.cc.gatech.edu/classes/AY2004/cs2335_spring/header.gif")
|
||||
between the two systems and let both independently download
|
||||
it from the internet.
|
||||
</p><p>
|
||||
<span class="bold"><b>EXTRA CREDIT OPTION:</b></span> For
|
||||
extra credit your team may support the use of an image that
|
||||
located on a local disk of one of the computers, here it is
|
||||
YOUR responsibility for transferring the image to the other
|
||||
computer. Do not assume that the other system has any other
|
||||
way of accessing the image (e.g. it's not on the internet or
|
||||
a networked drive).
|
||||
</p></td></tr></table></div></li><li style="list-style-type: disc">Text
|
||||
<span class="bold"><b>Insert Text:</b></span>
|
||||
Users should be able to insert text onto the drawing space. When
|
||||
inserting text, a user should have the ability to change the font
|
||||
of the text, along with the size and color of the text. The user
|
||||
will select a point on the screen which will be the starting point
|
||||
for displaying the text. Then the user should be able to type such
|
||||
that the text is constantly being updated on the graphics panel (i.e.
|
||||
you can not just have them type into a pop-up window). There should
|
||||
also be a button that allows the user to finalize their text and send
|
||||
it to everyone else. NOTE: When inserting text, you can assume that
|
||||
for each piece of text added there will be only one font type, size,
|
||||
and color. But the user should be able to change the font, size, and
|
||||
color anytime prior to pressing the "finalize" button.
|
||||
</li></ul></div><p>
|
||||
</p><p>
|
||||
<span class="bold"><b>TIPS:</b></span> Your team may find it helpful
|
||||
to visit the Graphics2D tutorial at
|
||||
<a href="http://java.sun.com/docs/books/tutorial/2d/display/index.html" target="_top">http://java.sun.com/docs/books/tutorial/2d/display/index.html</a>
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2787098"></a>3.4. Other Required Features</h3></div></div><p>
|
||||
</p><div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc"><span class="bold"><b>Save Session:</b></span>
|
||||
At any point in the editing session any user should be able
|
||||
save the current image to their local system. The format of
|
||||
the save file is up to you, but it is suggested that it be
|
||||
something simple (like a text file where the first thing on
|
||||
a line is the name of the shape added and then each parameter
|
||||
is listed after it).
|
||||
</li><li style="list-style-type: disc"><span class="bold"><b>Load Session:</b></span>
|
||||
At the start of an editing session the user should be prompted
|
||||
as to whether they wish to start a new image or load an
|
||||
existing one. If the user chooses to load an image it should
|
||||
be loaded in and treated as if each of the loaded commands were
|
||||
drawn at the start of the editing session by the person who
|
||||
loaded the file. <span class="emphasis"><em>NOTE: Your program MUST be able to
|
||||
load any of the images that were saved by your program (i.e.
|
||||
you must support your own file format, but do not need to
|
||||
support any other).</em></span></li><li style="list-style-type: disc"><span class="bold"><b>Undo:</b></span>
|
||||
At any point in time a user should be able to "undo" their
|
||||
previous command (if they just drew a line they would "undo"
|
||||
the whole line, not just the last point). Users should not
|
||||
be able to "undo" any command issued by another user (i.e.
|
||||
you can't undo a line drawn by someone else).
|
||||
</li><li style="list-style-type: disc"><span class="bold"><b>Super Undo (EXTRA CREDIT OPTION):</b></span>
|
||||
For extra credit, you can support the ability to "undo" any
|
||||
previous command that was done at any time (if the drawing was
|
||||
started from a saved file, this would include any of the commands
|
||||
used in creating that file). You will need to provide some method
|
||||
for the user to view a listing of all of the previous commands
|
||||
and easily selecting the one to undo. Unlike the normal "undo"
|
||||
function (listed above) this one permits any user to "undo" any
|
||||
command, even if they were not the one who originally issued
|
||||
it.
|
||||
</li><li style="list-style-type: disc"><span class="bold"><b>Chat:</b></span>
|
||||
The program must have a chat feature that works similar to the
|
||||
the basic chat programs we all know and love. :-) When displaying
|
||||
the messages it should display the user's name of "yourself" in
|
||||
one color and should display everyone else's user names in
|
||||
another color (red and blue are typical for this, but you are
|
||||
free to select any color that looks good).
|
||||
<span class="emphasis"><em>(See javax.swing.JTextPane, it permits the programmer
|
||||
to pass it HTML formatted text and then displays it as is
|
||||
appropriate.)</em></span><p>
|
||||
<span class="bold"><b>EXTRA CREDIT OPTION:</b></span> Provide
|
||||
support for using the most common emoticons (e.g. the user's
|
||||
typing :-P in the text input area will be translated into the
|
||||
appropriate icon when displayed in the received test area.
|
||||
</p></li><li style="list-style-type: disc"><span class="bold"><b>Help Screen:</b></span>
|
||||
Describes how to use your program.
|
||||
</li><li style="list-style-type: disc"><span class="bold"><b>About Screen:</b></span>
|
||||
Displays the name of the program and the names and GTNum's
|
||||
of the programmers.
|
||||
</li></ul></div><p>
|
||||
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2787274"></a>4. Suggested Design</h2></div></div><div class="section" lang="en"><div class="titlepage"></div><p>
|
||||
</p><div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc">
|
||||
ServerMain -
|
||||
<div class="itemizedlist"><ul type="opencircle"><li style="list-style-type: circle">
|
||||
Listens for new client new connections, and spawns new
|
||||
ServerThreads for each new incoming client connection.
|
||||
</li><li style="list-style-type: circle">
|
||||
Maintain a list of all currently connected clients
|
||||
</li><li style="list-style-type: circle">
|
||||
Must have to ability to broadcast messages to all connected
|
||||
clients
|
||||
</li><li style="list-style-type: circle">
|
||||
Handle client disconnects
|
||||
</li></ul></div></li><li style="list-style-type: disc">
|
||||
ServerThread - Implement Runnable interface -OR- Extend Thread
|
||||
<div class="itemizedlist"><ul type="opencircle"><li style="list-style-type: circle">
|
||||
Pass messages from the client to the ServerMain to be broadcast
|
||||
</li><li style="list-style-type: circle">
|
||||
Inform ServerMain of client disconnects
|
||||
</li></ul></div></li><li style="list-style-type: disc">
|
||||
ClientNetworking - Implement Runnable interface =OR= Extend Thread
|
||||
<div class="itemizedlist"><ul type="opencircle"><li style="list-style-type: circle">
|
||||
Open a connection to the server
|
||||
</li><li style="list-style-type: circle">
|
||||
Receive messages from the server and pass them to ClientMain.
|
||||
This will be the major/only functionality of the run method in
|
||||
the thread spawned in the ClientNetworking class.
|
||||
</li><li style="list-style-type: circle">
|
||||
Send messages to the server
|
||||
</li><li style="list-style-type: circle">
|
||||
Inform client main of server failure
|
||||
</li></ul></div></li><li style="list-style-type: disc">
|
||||
ClientMain -
|
||||
<div class="itemizedlist"><ul type="opencircle"><li style="list-style-type: circle">
|
||||
Initializes and displays all graphics components, associating
|
||||
all the components with the proper listeners.
|
||||
<pre class="screen">
|
||||
|
||||
Here is an example of how your program could look:
|
||||
|
||||
+-------------------------------------------------------------------------------------+
|
||||
| File | Options | Help |
|
||||
+-------------------------------------------------------------------------------------+
|
||||
| | |
|
||||
| | Rectangle |
|
||||
| | |
|
||||
| |-------------|
|
||||
| | |
|
||||
| | Circle |
|
||||
| | |
|
||||
| |-------------|
|
||||
| Graphics Display Panel | |
|
||||
| | Text |
|
||||
| | |
|
||||
| |-------------|
|
||||
| | |
|
||||
| | Polygons |
|
||||
| | |
|
||||
| |-------------|
|
||||
| | |
|
||||
| | etc |
|
||||
| | . |
|
||||
|-----------------------------------------------------------------------| . |
|
||||
| Option Bar - Change Color, Font Size, Font Type, etc... | . |
|
||||
+-----------------------------------------------------------------------+-------------+
|
||||
| |
|
||||
| Received Text Area |
|
||||
| |
|
||||
+-------------------------------------------------------------------------------------+
|
||||
| Text Input Area | Send Text Button |
|
||||
+-------------------------------------------------------------------------------------+
|
||||
</pre></li><li style="list-style-type: circle">
|
||||
Creates the ClientNetworking class and then initializes it
|
||||
</li><li style="list-style-type: circle">
|
||||
Has a method that accepts a message from the ClientNetworking and
|
||||
passes it to the proper component.
|
||||
</li></ul></div></li><li style="list-style-type: disc">
|
||||
GraphicsPanel - Extend JPanel (or if you are brave, Panel)
|
||||
<div class="itemizedlist"><ul type="opencircle"><li style="list-style-type: circle">
|
||||
Displays all of the drawn objects
|
||||
</li></ul></div></li><li style="list-style-type: disc">
|
||||
ClientEventListener - Implements MouseListener, ActionListener, KeyListener, MouseMotionListener
|
||||
<div class="itemizedlist"><ul type="opencircle"><li style="list-style-type: circle">
|
||||
Handle all keyboard, mouse, and button events.
|
||||
</li></ul></div></li><li style="list-style-type: disc">
|
||||
RenderableObject - <<Abstract>> representation of an object that can be drawn
|
||||
and an association with its owner. Should declare an abstract method "render" which must
|
||||
be overridden by all subclasses.
|
||||
<div class="itemizedlist"><ul type="disc"><li>
|
||||
RenderableImage - Contains reference to a picture (.jpeg, .gif, etc...) and have
|
||||
the ability to render it to a graphics object
|
||||
</li><li>
|
||||
RenderableText - Contains a string as well as any modifiers to the text (Size, Font Type, etc...)
|
||||
and have the ability to render it to a graphics object.
|
||||
</li><li>
|
||||
RenderableShape - Contains an object that implements the java.awt.Shape interface and have
|
||||
the ability to render it to a graphics object.
|
||||
</li></ul></div></li><li style="list-style-type: disc">
|
||||
RenderableObjectList - Implements List Interface
|
||||
<div class="itemizedlist"><ul type="opencircle"><li style="list-style-type: circle">
|
||||
Maintains a list of RenderableObjects
|
||||
</li><li style="list-style-type: circle">
|
||||
Ability to return a java.util.ListIterator
|
||||
</li><li style="list-style-type: circle">
|
||||
Must be able to save and load the list to/from a file
|
||||
</li></ul></div></li></ul></div><p>
|
||||
</p><p>
|
||||
Suggested Package Structure:
|
||||
</p><pre class="screen">
|
||||
- lab4
|
||||
- server
|
||||
* ServerMain (ex: lab4.server.ServerMain)
|
||||
* ServerThread
|
||||
- client
|
||||
* ClientMain
|
||||
- networking
|
||||
* ClientNetworking
|
||||
- model
|
||||
* RenderableObjectList
|
||||
* RenderableImage
|
||||
* RenderableShape
|
||||
* RenderableText
|
||||
* RenderableObject
|
||||
* ClientEventListener
|
||||
- gui
|
||||
* GraphicsPanel
|
||||
|
||||
Legend:
|
||||
"*" - Denotes a class
|
||||
"-" - Denotes a package
|
||||
</pre><p>
|
||||
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="http://www.cc.gatech.edu/classes/AY2003/cs2335_spring/labs/images/note.png"></td><th align="left">Note</th></tr><tr><td colspan="2" align="left" valign="top"><p>
|
||||
Your team is free to come up with an entirely new design, however
|
||||
partial-credit opportunities will be limited if you use another design.
|
||||
</p></td></tr></table></div></div></div><div class="section" lang="en"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2787680"></a>5. Deliverables</h2></div></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="http://www.cc.gatech.edu/classes/AY2003/cs2335_spring/labs/images/note.png"></td><th align="left">Note</th></tr><tr><td colspan="2" align="left" valign="top"><p>
|
||||
We will not be checking PMD or Checkstyle for Part 1 or 2, but we
|
||||
STRONGLY recommend you keep both tools in mind when programming.
|
||||
</p></td></tr></table></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2787698"></a>5.1. Deliverables for Part 1</h3></div></div><p>For the first part of the lab, you need to fully implement the server
|
||||
component of your system. You should be able to ssh into your sever and
|
||||
perform any commands, which should then be properly broadcast to all other
|
||||
connected clients. Although your server must support all message types, you
|
||||
may still change them for the further deliverables if necessary.
|
||||
</p><p>
|
||||
One of your group members must turn in the following:
|
||||
</p><div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc">All source code needed to run your program.</li><li style="list-style-type: disc">The Ant build-file (build.xml), which needs to contain
|
||||
the following targets (with the appropriate dependencies):
|
||||
<div class="itemizedlist"><ul type="disc"><li>run - Runs your program and should be the default target</li><li>build - Compiles your program</li><li>checkstyle - Runs Checkstyle on your source code</li><li>pmd - Runs PMD on your source code</li><li>jar - Creates an executable Jar of your program</li><li>javadoc - Creates the JavaDoc for your program
|
||||
(NOTE: JavaDoc must not produce any errors/warning to receive credit)</li><li>clean - Removes all files created from all other targets</li></ul></div></li><li style="list-style-type: disc">The completed Part 1 readme file ("P1_README.txt").
|
||||
</li></ul></div><p>
|
||||
Please submit an archive of all these files in one of
|
||||
the following formats: zip, tar, jar, or gzip.
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2787792"></a>5.2. Deliverables for Part 2</h3></div></div><p>
|
||||
For the second part of the project, you must submit everything from
|
||||
Part 1 and the basic client, which needs to support the following
|
||||
features:
|
||||
</p><div class="itemizedlist"><ul type="disc"><li>
|
||||
Chat
|
||||
</li><li>
|
||||
Drawing of a simple black line
|
||||
</li><li>
|
||||
Undo
|
||||
</li><li>
|
||||
Must properly communicate with the Server and receive updates
|
||||
from other clients
|
||||
</li><li>
|
||||
About screen
|
||||
</li></ul></div><p>
|
||||
</p><p>
|
||||
One of your group members must turn in the following:
|
||||
</p><div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc">All source code needed to run your program.</li><li style="list-style-type: disc">The Ant build-file (build.xml)</li><li style="list-style-type: disc">The completed Part 2 readme file ("P2_README.txt").
|
||||
</li></ul></div><p>
|
||||
Please submit an archive of all these files in one of
|
||||
the following formats: zip, tar, jar, or gzip.
|
||||
</p></div><div class="section" lang="en"><div class="titlepage"><div><h3 class="title"><a name="id2787868"></a>5.3. Deliverables for Part 3</h3></div></div><p>
|
||||
For the final part of the lab, you must submit everything from
|
||||
Part 1 and Part 2, but now everything must be fully functional.
|
||||
</p><p>
|
||||
One of your group members must turn in the following:
|
||||
</p><div class="itemizedlist"><ul type="bullet"><li style="list-style-type: disc">All source code needed to run your program.</li><li style="list-style-type: disc">The Ant build-file (build.xml)</li><li style="list-style-type: disc">The completed Part 3 readme file ("P3_README.txt").
|
||||
</li></ul></div><p>
|
||||
Please submit an archive of all these files in one of
|
||||
the following formats: zip, tar, jar, or gzip.
|
||||
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2787914"></a>6. Extra Credit</h2></div></div><p>
|
||||
You may receive up to 20 points of extra credit for Part 3 of this lab.
|
||||
You may attempt the following for extra credit (and their point values):
|
||||
</p><div class="itemizedlist"><ul type="disc"><li>Amazing UI (to be determined by your TA) - 5pt</li><li>Image File Transfer (Non-URL) - 10pt</li><li>Super Undo - 5pt</li><li>Emoticons - 2pt</li><li>File Saving/Loading from (non-trivial) XML - 5pt</li></ul></div><p>
|
||||
</p></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="http://www.cc.gatech.edu/classes/AY2003/cs2335_spring/labs/images/important.png"></td><th align="left">Important</th></tr><tr><td colspan="2" align="left" valign="top"><p>
|
||||
Unless arranged in advance, your TA will be grading this assignment
|
||||
on the RedHat systems available in the States Lab and will be using
|
||||
the Java tools provided in the "~cs2335/" directory. It is YOUR
|
||||
responsibility to verify that your program will work on these
|
||||
systems prior to submitting it.
|
||||
</p></td></tr></table></div></div></body></html>
|
||||
Reference in New Issue
Block a user