Skip to content
Snippets Groups Projects
Commit 7854dccb authored by Chang Che Hao's avatar Chang Che Hao
Browse files

Merge branch 'CheHao' into 'master'

Add RMI infrastructure

See merge request !5
parents d7167407 ce8a2e4a
No related branches found
No related tags found
3 merge requests!8Master,!6Master -> hai,!5Add RMI infrastructure
Showing
with 937 additions and 7 deletions
package GUI;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RectangularShape;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class DrawingArea extends JPanel {
/// enum for all different mode ///
enum Mode { FREEHAND, LINE, CIRCLE, RECTANGLE, OVAL, ERASE }
/// Canvas size parameter ///
private final static int AREA_WIDTH = 600;
private final static int AREA_HEIGHT = 500;
/// Shape to be drawn on the canvas ///
private Shape drawing;
private Point startPoint;
private Point previousPoint;
private Point currentPoint;
/// Default mode and color ///
private Color shapeColor = new Color(0, 0, 0);
private Mode currentMode = Mode.FREEHAND;
/// Create a empty canvas ///
private BufferedImage image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB);
/// Drawing tool
private Graphics2D g2 = (Graphics2D) image.getGraphics();
public DrawingArea() {
setBackground(Color.WHITE); // Set Background color
setDoubleBuffered(false); // Non-buffered drawing
/// Antialiasing the graphic for smoothness ///
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
/// Mouse listeners for pressing///
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
startPoint = previousPoint = e.getPoint();
/// Instantiate object based on current mode ///
switch (currentMode) {
case FREEHAND:
case LINE:
drawing = new Line2D.Double();
break;
case ERASE:
case CIRCLE:
case OVAL:
drawing = new Ellipse2D.Double();
break;
case RECTANGLE:
drawing = new Rectangle2D.Double();
break;
}
}
});
/// Mouse motion listeners for dragging ///
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
currentPoint = e.getPoint();
int x = Math.min(startPoint.x, e.getX());
int y = Math.min(startPoint.y, e.getY());
int width = Math.abs(startPoint.x - e.getX());
int height = Math.abs(startPoint.y - e.getY());
switch (currentMode) {
/// Freehand drawing is continuously drawing line from current point to previous point ///
case FREEHAND:
((Line2D) drawing).setLine(currentPoint, previousPoint);
g2.setColor(shapeColor);
g2.draw(drawing);
previousPoint = currentPoint;
break;
/// Single line ///
case LINE:
((Line2D) drawing).setLine(startPoint, currentPoint);
break;
/// Eraser is continuously drawing "small white circle" from current point to previous point ///
case ERASE:
((Ellipse2D) drawing).setFrame(currentPoint.getX(), currentPoint.getY(), 10, 10);
g2.setColor(Color.WHITE);
g2.fill(drawing);
g2.draw(drawing);
break;
/// Single circle (How to draw more intuitively?)///
case CIRCLE:
double radius = Math.sqrt(width * width + height * height);
// ((Ellipse2D) drawing).setFrame(x, y, radius, radius);
((Ellipse2D) drawing).setFrame(startPoint.getX() - radius, startPoint.getY() - radius, 2 * radius, 2 * radius);
break;
/// Single oval ///
case OVAL:
((Ellipse2D) drawing).setFrame(x, y, width, height);
break;
/// Single rectangle ///
case RECTANGLE:
((Rectangle2D) drawing).setFrame(x, y, width, height);
break;
}
repaint();
}
});
/// Mouse listener for releasing ///
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
/// Draw the final drawing to the buffered image ///
switch (currentMode) {
case OVAL:
case RECTANGLE:
case CIRCLE:
/// Abort drawing if 2D has no width or height ///
if (((RectangularShape) drawing).getWidth() == 0 || ((RectangularShape) drawing).getHeight() == 0) {
break;
}
case FREEHAND:
case LINE:
// Graphics2D g2 = (Graphics2D) image.getGraphics();
g2.setColor(shapeColor);
/// Uncomment the line below to fill the shapes with color ///
// g2.fill(drawing);
g2.draw(drawing);
}
g2 = (Graphics2D) image.getGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(shapeColor);
/// This repaint is needed if we want to fill the drawing shape with color
repaint();
drawing = null;
}
});
}
@Override
public Dimension getPreferredSize()
{
return isPreferredSizeSet() ?
super.getPreferredSize() : new Dimension(AREA_WIDTH, AREA_HEIGHT);
}
/// Create a white image to clear previous drawing ///
public void clear() {
image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB);
g2 = (Graphics2D) image.getGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
/// Draw the whole image on JPanel ///
if (image != null) {
g.drawImage(image, 0, 0, null);
}
/// Draw temporary shape ///
if (drawing != null) {
Graphics2D g2 = (Graphics2D) g;
/// Eraser has no border color ///
Color borderColor = currentMode != Mode.ERASE ? shapeColor : Color.WHITE;
g2.setColor(borderColor);
g2.draw(drawing);
}
}
/// File manipulations (PNG only) ///
public void saveFile() {
try {
ImageIO.write(image, "PNG", new File("Saved_White_Board.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void saveAsFile(File file) {
try {
ImageIO.write(image, "PNG", file);
} catch (IOException e) {
e.printStackTrace();
}
}
public void openFile(File file) {
try {
image = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
}
repaint();
}
/// Drawing mode setters ///
public void setModeFreehand() {
currentMode = Mode.FREEHAND;
}
public void setModeLine() {
currentMode = Mode.LINE;
}
public void setModeCircle() {
currentMode = Mode.CIRCLE;
}
public void setModeRectangle() {
currentMode = Mode.RECTANGLE;
}
public void setModeOval() {
currentMode = Mode.OVAL;
}
public void setModeErase() {
currentMode = Mode.ERASE;
}
/// Drawing color setters ///
public void setColorAqua() {
shapeColor = new Color(0,255, 255);
}
public void setColorBlack() {
shapeColor = new Color(0, 0, 0);
}
public void setColorBlue() {
shapeColor = new Color(0, 0, 255);
}
public void setColorFuchsia() {
shapeColor = new Color(255, 0, 255);
}
public void setColorGray() {
shapeColor = new Color(128, 128, 128);
}
public void setColorGreen() {
shapeColor = new Color(0, 128, 0);
}
public void setColorLime() {
shapeColor = new Color(0, 255, 0);
}
public void setColorMaroon() {
shapeColor = new Color(128,0, 0);
}
public void setColorNavy() {
shapeColor = new Color(0, 0, 128);
}
public void setColorOlive() {
shapeColor = new Color(128, 128, 0);
}
public void setColorPurple() {
shapeColor = new Color(128, 0, 128);
}
public void setColorRed() {
shapeColor = new Color(255, 0, 0);
}
public void setColorSilver() {
shapeColor = new Color(192, 192, 192);
}
public void setColorTeal() {
shapeColor = new Color(0, 128, 128);
}
public void setColorWhite() {
shapeColor = new Color(255, 255, 255);
}
public void setColorYellow() {
shapeColor = new Color(255, 255, 0);
}
}
\ No newline at end of file
package GUI;
import javax.swing.*;
public class MenuBar extends JMenuBar {
JButton clearBtn, newBtn, openBtn, saveBtn, saveAsBtn, closeBtn;
}
package GUI;
import javax.swing.*;
import java.awt.*;
public class ToolBar extends JPanel {
private DrawingArea drawingArea;
public ToolBar() {
}
}
class Tools extends JPanel {
}
class ColorPallete extends JPanel {
private Color color;
public ColorPallete() {
this.color = new Color(0, 0, 0); // Black
}
public void setColor(Color color) {
this.color = color;
}
public void setColorRBG(int r, int b, int g) {
this.color = new Color(r, b, g);
}
public Color getColor() {
return this.color;
}
public void setColorAqua() {
this.color = new Color(0,255, 255);
}
public void setColorBlack() {
this.color = new Color(0, 0, 0);
}
public void setColorBlue() {
this.color = new Color(0, 0, 255);
}
public void setColorFuchsia() {
this.color = new Color(255, 0, 255);
}
public void setColorGray() {
this.color = new Color(128, 128, 128);
}
public void setColorGreen() {
this.color = new Color(0, 128, 0);
}
public void setColorLime() {
this.color = new Color(0, 255, 0);
}
public void setColorMaroon() {
this.color = new Color(128,0, 0);
}
public void setColorNavy() {
this.color = new Color(0, 0, 128);
}
public void setColorOlive() {
this.color = new Color(128, 128, 0);
}
public void setColorPurple() {
this.color = new Color(128, 0, 128);
}
public void setColorRed() {
this.color = new Color(255, 0, 0);
}
public void setColorSilver() {
this.color = new Color(192, 192, 192);
}
public void setColorTeal() {
this.color = new Color(0, 128, 128);
}
public void setColorWhite() {
this.color = new Color(255, 255, 255);
}
public void setColorYellow() {
this.color = new Color(255, 255, 0);
}
}
\ No newline at end of file
package client;
import java.net.InetAddress;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Scanner;
import remote.IClientController;
import remote.IDrawingController;
import remote.IUpdateController;
/**
* This class retrieves a reference to the remote object from the RMI registry.
* It invokes the methods on the remote object as if it was a local object of the type of the
* remote interface.
*
*/
public class Client {
private static int id;
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
try {
//Connect to the rmiregistry that is running on localhost
Registry registryServer = LocateRegistry.getRegistry("localhost");
// Registry registryServer = LocateRegistry.getRegistry("10.13.64.162");
IClientController clientController = (IClientController) registryServer.lookup("ClientController");
//Create rmiregistry for server to send commands that requests client to update drawing, chat, etc...
IUpdateController updateController = new UpdateController();
Registry registryClient = LocateRegistry.getRegistry();
registryClient.rebind("UpdateController", updateController);
// RMI client will give a stub of itself to the server
// Remote aRemoteObj = (Remote) UnicastRemoteObject.exportObject(new UpdateController(), 0);
//Call methods on the remote object as if it was a local object
System.out.println("Client: calling remote methods");
String result = clientController.joinServer("Hai", InetAddress.getLocalHost(), "UpdateController");
System.out.println(result);
// Test commands
ArrayList<String> usernameList = new ArrayList<>();
String command;
while(true) {
command = keyboard.nextLine();
switch (command) {
case "test1":
usernameList = clientController.getUsernameList();
if (!usernameList.isEmpty()) {
for (int i = 0; i < usernameList.size(); i++) {
System.out.println(usernameList.get(i));
}
}
break;
default:
System.out.println("nothing");
break;
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package client;
import remote.IClientController;
import remote.IDrawingController;
import remote.IUpdateController;
import java.net.InetAddress;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
/**
* This class retrieves a reference to the remote object from the RMI registry.
* It invokes the methods on the remote object as if it was a local object of the type of the
* remote interface.
*
*/
public class Client2 {
private static int id;
public static void main(String[] args) {
try {
//Connect to the rmiregistry that is running on localhost
Registry registryServer = LocateRegistry.getRegistry("localhost");
IDrawingController drawingController = (IDrawingController) registryServer.lookup("DrawingController");
IClientController clientController = (IClientController) registryServer.lookup("ClientController");
//Create rmiregistry for server to send commands that requests client to update drawing, chat, etc...
IUpdateController updateController = new UpdateController();
Registry registryClient = LocateRegistry.getRegistry();
registryClient.rebind("UpdateController", updateController);
//Call methods on the remote object as if it was a local object
System.out.println("Client: calling remote methods");
String result = clientController.joinServer("HaiHai", InetAddress.getLocalHost(), "UpdateController");
System.out.println(result);
while(true);
}catch(Exception e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package client;
import GUI.DrawingArea;
import remote.IClientController;
import remote.IDrawingController;
import server.User;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Observable;
public class ClientCanvas extends Observable {
private static int id=1;
private IClientController clientController;
private IDrawingController drawingController;
private ArrayList<User> users;
private DrawingArea drawing;
public ClientCanvas() {
users = new ArrayList<>();
drawing = new DrawingArea();
try {
//Connect to the rmiregistry that is running on localhost
Registry registry = LocateRegistry.getRegistry("localhost");
//Retrieve the stub/proxy for the remote math object from the registry
this.drawingController = (IDrawingController) registry.lookup("DrawingController");
this.clientController = (IClientController) registry.lookup("ClientController");
//Call methods on the remote object as if it was a local object
System.out.println("Client: calling remote methods");
// clientController.addClient(id);
}catch(Exception e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package client;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
......@@ -47,7 +45,7 @@ public class DrawingArea extends JPanel {
public DrawingArea() {
/// Antialiasing the graphic for smoothness ///
// g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
/// Set Background color ///
setBackground(Color.WHITE);
......
package client;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
......
package client;
import remote.IUpdateController;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
public class UpdateController extends UnicastRemoteObject implements IUpdateController, Serializable {
private ArrayList<String> userList;
protected UpdateController() throws RemoteException {
userList = new ArrayList<>();
}
@Override
public void updateClient(String text) throws RemoteException {
System.out.println("Client " + text + " just joined the server.");
userList.add(text);
}
@Override
public ArrayList<String> getUserList() throws RemoteException {
return userList;
}
@Override
public void updateUserList(ArrayList userList) throws RemoteException {
this.userList = userList;
}
}
package remote;
import java.io.Serializable;
import java.net.InetAddress;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
public interface IClientController extends Remote {
public String joinServer(String userName, InetAddress ipAddress, String rmiName) throws RemoteException;
public ArrayList<String> getUsernameList() throws RemoteException;
}
package remote;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* RMI Remote interface - must be shared between client and server.
* All methods must throw RemoteException.
* All parameters and return types must be either primitives or Serializable.
*
* Any object that is a remote object must implement this interface.
* Only those methods specified in a "remote interface" are available remotely.
*/
public interface IDrawingController extends Remote {
public double drawLine(double a, double b) throws RemoteException;
public double drawRectangle(double a, double b) throws RemoteException;
}
package remote;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
/**
* RMI Remote interface - IRemoteUpdate.
* Allows Server to command Client to update: canvas, chat, other.
*/
public interface IUpdateController extends Remote {
public void updateClient(String text) throws RemoteException;
public ArrayList<String> getUserList() throws RemoteException;
public void updateUserList(ArrayList userList) throws RemoteException;
}
package server;
import java.io.Serializable;
import java.net.InetAddress;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import client.UpdateController;
import remote.IClientController;
import remote.IUpdateController;
/**
* Server side implementation of the remote interface.
* Must extend UnicastRemoteObject, to allow the JVM to create a
* remote proxy/stub.
*
*/
public class ClientController extends UnicastRemoteObject implements IClientController, Serializable {
/**
* Added
*/
//private static final long serialVersionUID = 1L;
private ArrayList<User> userList;
protected ClientController() throws RemoteException {
userList = new ArrayList<>();
}
@Override
public String joinServer(String userName, InetAddress ipAddress, String rmiName) throws RemoteException {
try
{
Registry userRMI = LocateRegistry.getRegistry(ipAddress.getHostAddress());
IUpdateController updateController = (IUpdateController) userRMI.lookup(rmiName);
User user = new User(userName, ipAddress, rmiName);
userList.add(user);
for (User u : userList) {
if (!userName.equals(u.getUsername())) {
u.getUpdateController().updateClient(userName);
}
}
System.out.println("User " + userName + " added successfully");
}
catch (Exception e)
{
e.printStackTrace();
}
return "update successfully";
}
@Override
public ArrayList<String> getUsernameList() throws RemoteException {
ArrayList<String> usernameList = new ArrayList<>();
for (User u : userList) {
usernameList.add(u.getUsername());
}
return usernameList;
}
}
\ No newline at end of file
package server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import remote.IDrawingController;
/**
* Server side implementation of the remote interface.
* Must extend UnicastRemoteObject, to allow the JVM to create a
* remote proxy/stub.
*
*/
public class DrawingController extends UnicastRemoteObject implements IDrawingController {
/**
* Added
*/
//private static final long serialVersionUID = 1L;
private int numberOfComputations;
protected DrawingController() throws RemoteException {
numberOfComputations = 0;
}
@Override
public double drawLine(double a, double b) throws RemoteException {
return a+b;
}
@Override
public double drawRectangle(double a, double b) throws RemoteException {
return 0;
}
}
\ No newline at end of file
package server;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Scanner;
import remote.IClientController;
import remote.IDrawingController;
public class Server extends Observable {
public static void main(String[] args) {
try {
//Export the remote math object to the Java RMI runtime so that it
//can receive incoming remote calls.
//Because RemoteMath extends UnicastRemoteObject, this
//is done automatically when the object is initialized.
//
//RemoteMath obj = new RemoteMath();
//IRemoteMath stub = (IRemoteMath) UnicastRemoteObject.exportObject(obj, 0);
//
IDrawingController drawingController = new DrawingController();
IClientController clientController = new ClientController();
//Publish the remote object's stub in the registry under the name "Compute"
Registry registry = LocateRegistry.getRegistry();
registry.rebind("DrawingController", drawingController);
registry.rebind("ClientController", clientController);
System.out.println("Server is ready");
// Test client update command
// Get client registry
ArrayList<String> usernameList = new ArrayList<>();
Scanner keyboard = new Scanner(System.in);
String command;
while(true) {
command = keyboard.nextLine();
switch (command) {
case "test1":
usernameList = clientController.getUsernameList();
if (!usernameList.isEmpty()) {
for (int i = 0; i < usernameList.size(); i++) {
System.out.println(usernameList.get(i));
}
}
break;
default:
System.out.println("nothing");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package server;
import java.rmi.RemoteException;
public class ServerDriver {
private ClientController clientController;
private DrawingController drawingController;
private ServerDriver() throws RemoteException {
try {
this.clientController = new ClientController();
this.drawingController = new DrawingController();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
package server;
import remote.IUpdateController;
import java.net.InetAddress;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class User {
private String userName;
private String RMIName;
private InetAddress ipAddress;
private IUpdateController updateController;
public User (String username, InetAddress ipAddress, String rmiName) throws RemoteException, NotBoundException {
this.userName = username;
this.ipAddress = ipAddress;
this.RMIName = rmiName;
Registry userRMI = LocateRegistry.getRegistry(ipAddress.getHostAddress());
this.updateController = (IUpdateController) userRMI.lookup(rmiName);
}
public String getUsername()
{
return userName;
}
public InetAddress getIpAddress()
{
return ipAddress;
}
public String getRMIname()
{
return RMIName;
}
public IUpdateController getUpdateController()
{
return updateController;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment