Up | Previous | Next |
So first the client changes:
The server needs to change next, in two places (brown, blue):
import java.awt.*; import javax.swing.*; import java.rmi.*; import java.rmi.server.*; import java.awt.event.*; public class Client extends JFrame implements ClientInterface, KeyListener { public Client(int columns, int rows) { this.setTitle("iceblox: client frame"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(columns * cellWidth + cellWidth / 2, (1 + rows) * cellHeight + cellHeight / 2); getContentPane().add(new Surface(columns, rows), "Center"); addKeyListener(this); this.setVisible(true); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { int val = e.getKeyCode(); try { if (val == 38) server.broadcast(id, "up"); else if (val == 39) server.broadcast(id, "right"); else if (val == 40) server.broadcast(id, "down"); else if (val == 37) server.broadcast(id, "left"); } catch (Exception exception) { System.out.println("Glitch: " + exception); } } int cellWidth = 30, cellHeight = 30; class Surface extends JPanel { int columns, rows; Surface(int columns, int rows) { this.columns = columns; this.rows = rows; } int fontSize = 10; // in pixels Font digitsFont = new Font("Serif", Font.PLAIN, fontSize); public void paintComponent(Graphics g) { super.paintComponent(g); ((Graphics2D)g).setFont(digitsFont); g.setColor(Color.black); g.fillRect(0, 0, columns * cellWidth, rows * cellHeight); g.setColor(Color.gray); for (int i = 0; i <= rows; i++) g.drawLine(0, i * cellHeight, columns * cellWidth, i * cellHeight); for (int i = 0; i < columns; i++) { g.drawLine(i * cellWidth, 0, i * cellWidth, rows * cellHeight); g.drawRect(0, 0, cellWidth * columns, cellHeight * rows); g.setColor(Color.gray); } for (int j = 0; j < columns; j = j + 1) for (int i = 0; i < rows; i++) g.drawString(i + ", " + j, j * cellWidth + 2, i * cellHeight + fontSize); } } ServerInterface server; public void registerWith(ServerInterface server) throws RemoteException { this.server = server; this.id = server.register(this); System.out.println("I have registered, I have id: " + this.id); } int id = -1; public static void main(String[] args) { try { ServerInterface far = (ServerInterface)Naming.lookup("rmi://" + args[0] + ":" + args[1] + "/Dirac"); int cols = 10, rows = 10; Client here = new Client(cols, rows); UnicastRemoteObject.exportObject(here); here.registerWith(far); } catch (Exception e) { System.out.println("Error in client..." + e); e.printStackTrace(); } } }
The server interface needs to support one of these changes:
import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; public class Server extends UnicastRemoteObject implements ServerInterface { public Server() throws RemoteException { System.out.println("Server being initialized..."); } ClientInterface[] clients = new ClientInterface[100]; public synchronized int register(ClientInterface client) throws RemoteException { size++; try { clients[size] = client; } catch (Exception e) { System.out.println("Darn: " + e); } return size; } int size = -1; public void broadcast(int id, String action) throws RemoteException { for (int i = 0; i <= size; i++) { clients[i].update(id, action); } } public static void main(String[] args) { System.setSecurityManager(new RMISecurityManager()); try { Server pam = new Server(); Registry cat = LocateRegistry.createRegistry(Integer.parseInt(args[0])); cat.bind("Dirac", pam); System.out.println("Server is ready..."); } catch (Exception e) { System.out.println("Server error: " + e + "... "); } } }
The content of broadcast calling update, the client changes again.
import java.rmi.*; public interface ServerInterface extends Remote { public int register(ClientInterface client) throws RemoteException; public void broadcast(int name, String action) throws RemoteException; }
The client interface also.
import java.awt.*; import javax.swing.*; import java.rmi.*; import java.rmi.server.*; import java.awt.event.*; public class Client extends JFrame implements ClientInterface, KeyListener { public Client(int columns, int rows) { this.setTitle("iceblox: client frame"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(columns * cellWidth + cellWidth / 2, (1 + rows) * cellHeight + cellHeight / 2); getContentPane().add(new Surface(columns, rows), "Center"); addKeyListener(this); this.setVisible(true); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { int val = e.getKeyCode(); try { if (val == 38) server.broadcast(id, "up"); else if (val == 39) server.broadcast(id, "right"); else if (val == 40) server.broadcast(id, "down"); else if (val == 37) server.broadcast(id, "left"); } catch (Exception exception) { System.out.println("Glitch: " + exception); } } int cellWidth = 30, cellHeight = 30; class Surface extends JPanel { int columns, rows; Surface(int columns, int rows) { this.columns = columns; this.rows = rows; } int fontSize = 10; // in pixels Font digitsFont = new Font("Serif", Font.PLAIN, fontSize); public void paintComponent(Graphics g) { super.paintComponent(g); ((Graphics2D)g).setFont(digitsFont); g.setColor(Color.black); g.fillRect(0, 0, columns * cellWidth, rows * cellHeight); g.setColor(Color.gray); for (int i = 0; i <= rows; i++) g.drawLine(0, i * cellHeight, columns * cellWidth, i * cellHeight); for (int i = 0; i < columns; i++) { g.drawLine(i * cellWidth, 0, i * cellWidth, rows * cellHeight); g.drawRect(0, 0, cellWidth * columns, cellHeight * rows); g.setColor(Color.gray); } for (int j = 0; j < columns; j = j + 1) for (int i = 0; i < rows; i++) g.drawString(i + ", " + j, j * cellWidth + 2, i * cellHeight + fontSize); } } public void update(int player, String action) { System.out.println("Player " + this.id + " updated by player " + player + " with action: " + action); } ServerInterface server; public void registerWith(ServerInterface server) throws RemoteException { this.server = server; this.id = server.register(this); System.out.println("I have registered, I have id: " + this.id); } int id = -1; public static void main(String[] args) { try { ServerInterface far = (ServerInterface)Naming.lookup("rmi://" + args[0] + ":" + args[1] + "/Dirac"); int cols = 10, rows = 10; Client here = new Client(cols, rows); UnicastRemoteObject.exportObject(here); here.registerWith(far); } catch (Exception e) { System.out.println("Error in client..." + e); e.printStackTrace(); } } }
We can test then the chat (both ways). First the monolithic setup:
import java.rmi.*; public interface ClientInterface extends Remote{ public void update(int player, String action) throws RemoteException; }
And here's how it runs as separate programs on the local host:
We have four windows stacked in this last snapshot, for one server and three clients.
This page needs to be split into several, one for each change/step taken (maybe, maybe not).
Now let's make the clients visible in the shared world.
Up | Previous | Next |