Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CPAN322 Java Application Programming Lecture #8: Networking Networking programming enable us to write applications that communicate with other applications running on the internet via a well-known set of protocols. One of the key strengths in Java is its strong support and integration with internet networking. The package java.net provides the required classes and interfaces for implementing networking applications and internet programming. The socket classes, for example, enable us to communicate with any server on the Internet or implement our own Internet server. The URL classes on the other hand enable us to communicate with a web server. Internet Protocols The internet is a set of worldwide collection of networks, routing equipment and computers using a common set of protocols to define how each party will interact with each other. A protocol is a set of rules that govern the communication of information. Many protocols exist in computer networking. The Internet Protocol is the main protocol used to connect computers over the internet. Each computer is uniquely identified using a mechanism called IP address. Currently IP addresses are 32 bit length and each is denoted by sequence of 4 subnumbers between 0 and 255 ( for example 192.168.1.1). Since IP addresses are hard to remember, another mechanism called domain names can be used instead ( for example www.mysite.com). IP doesn't understand domain names, therefore the service DNS is used to translated a domain name to an IP address. The Internet Protocol family includes IP and all higher-level network protocols built on top of it, such as TCP, UDP, HTTP, SMTP and FTP. When IP transmit data between two computers, it breaks the data into smaller pieces of information called packets. Packets are numbered and sent separately via different routs through the internet. They are assembled by the recipient in the correct order. The IP functionality is to transmit the data to the destination without verifying that data is received as it was sent . Therefore it is known as a connectionless protocol. Therefore a higher level protocols such as TCP are used on top of IP for this reason. 1 The TCP is a connection oriented, continuous stream protocol that attempts to reliably deliver the data over the internet. The UDP is a connectionless protocol that is an alternative to TCP for host to host communications. It does not validate that data is received as it is sent. UDP ports are distinct from TCP ports. The HTTP describes how to exchange information on the internet between a web browser and a web server. To locate resources on the internet, a standard format known as the URL is used. An HTTP request message sent by a client to the web server has the following format: request line zero or more header lines a blank line an optional message body The request line includes the request method, the URL and the protocol version (for example GET /index.html HTTP/1.0) Following is a list of the request methods under HTTP: Method Description GET Return the required file POST Send data to be processed by the server PUT Store a file on the server DELETE Delete a file from the server TRACE Trace the server communications OPTIONS Request options supported by the server HEAD Request only the header information Date are sent to the server in the format: name1=val1&name2=val2&... If GET method is used, the data will be appended to the end of the request after a question mark. For example: http://hal.humberc.on.ca/~abdullah/cgimarks.cgi?id=123&pass=abcd If POST method is used, then the data will be embedded to the request header. 2 An TTTP response message from the server to the client has the following format: status line zero or more header lines a blank line an optional message body The status line includes: the protocol version, response status code, and the reason phrase describing the status code (for example HTTP/1.0 200 OK) The FTP governs the transfer of data over the internet. The SMTP describes how to transfer email across the internet Open Source Interconnection Model: The OSI module was developed by the ISO that describe 7 various layers of abstractions for network software and hardware. According to this module, any layer can call on services from the layer immediately below. 7. Application Layer 6. Presentation Layer 5. Session Layer 4. Transport Layer 3. Network Layer 2. Data Link Layer 1. Physical Layer Following is a description of each layer: Application Layer Contains network applications that users interact with , such as email, file transfer, and web browsers. Presentation Layer Implements data presentation services, such as data encryption and data compression. Session Layer Manage connection sessions 3 Transport Layer Ensure that data is received exactly as it is sent. Network Layer Manage connections across the network. Data Link Layer Transmits and receives packets of information reliably across a uniform physical network Physical Layer Defines the physical properties of the network. According to this module, the IP lies at the 3rd level. Both TCP and UDP lie at the 4th level. The TCP works on top of the IP. Networking in Java: Java provides the package java.net for supporting networking programming. Java's socket-based networking enable the programmer to easily implements client/server application. The socket-based client server applications view the networking as if it was file I/O. Sockets are a programming abstraction that provide communication channels through which computers can communicate over the network. Java provides two kinds of socket-based communications where processes can connect to each other: stream socket and datagram sockets. Stream socket provide a connection oriented service where data is transmitted between services in continuous streams using the TCP. Datagram sockets provide a connectionless service where data is broken into multiple packets and transmitted using UDP . The packets are not delivered in any particular order. Packets may be lost, duplicated or arrive out of sequence. Using datagram sockets require extra programming to make sure that all the packets are received and they are reassembled in the proper order. In order for the clients to communicate with the server, the server should create a socket at a certain port and wait for clients connections. A port is an address or entry point on the host computer. The clients must connect to the server using this specific port. Standard application protocols are assigned well known ports. Port numbers below 1024 are reserved for system use and should not be used by application programs. Some well know port numbers are: 21 FTP 23 Telnet 25 SMTP 79 Finger 80 HTTP 4 I will explain both stream-based sockets and datagram-based , but we will work only with stream sockets in this course, since it is the most popular technique. Creating client server applications using Stream Socket communications: . Creating a server involves the following steps: Create a server socket object: ServerSocket ss=new ServerSocket(port,maxNoOfCleints); This statement establish the port on which the server will wait for clients connections. A client connection is automatically refused if the number of connected clients has exceeded the maximum limit. The server must listen for a client request: Socket connection=ss.accept(); Get an output stream and an input stream to communicate with the client InputStream in=s.getInputStream(); OutputStream out=s.getOutputStream(); This enable the server to send and receive data in binary format. We can chain other types of streams to send and receive data in different format. For example to send and receive character data, we can chain the streams as follows: BufferedReader reader=new BufferedReader(new InputStreamReader(in)); PrintWriter writer=new PrintWriter(out); To send and receive objects instead of primitive data types, we chain the streams as follows: ObjectInputStream inputstream=new ObjectInputStream(in); ObjectOutputStream outputstream=new ObjectOutputStream(out); 5 Communicate with the client(s). If the data is transmitted in binary format, then the read method of the ImputStream object should be used to receive the data, and the write method of the OutputStream object to send the data. If the data is transmitted in text format, then we should use the readLine method of the BufferedReader object to get the data from the client(s). To send character data to the client we use print and flush methods of the PrintWriter object. Since the PrintWriter object buffers the character data, the user of flush method is required to empty the buffer and forward all the waiting characters to the client(s). If the data is transmitted as objects, then we should use the readObject method of the ObjectInputStream object to receive objects from the client(s) and the writeObject method of the ObjectOutputStream object to send objects. When the server is done communicating with the client(s), the socket must be closed: s.close(); In order for the server to manage more than one client at a time, it must be multithreaded. The server can then create a separate thread for each client connection. Creating a client application involves the following steps: Create a socket to connect to the server: Socket cs=new Socket(serverIPAddress,serverPort); Get an output stream and an input stream to communicate with the server. The client and the server must send and receive data in the same format. Send data to and receive data from the server. Close the socket after the client finishes communicating with the server. Creating client server applications using Datagram Socket communications: Creating a server involves the following steps: Create a datagram socket object: DatagramSocket ds=new DatagramSocket(port); 6 Create one DtagramPacket object to send packets to the client(s) and one DatagramPacket object to receive packets from the client(s). The server must wait for a packet to arrive: byte data[] = new byte[ 100 ]; receivePacket = new DatagramPacket( data, data.length ); // wait for packet ds.receive( receivePacket ); The server can send packets to the client(s) using send method of the socket object When the server is done, close the socket connection . ds.close(); Creating a client application involves the following steps: Create a socket to connect to the server: Socket cs=new Socket(serverIPAddress,serverPort); Receive packets from the server. For example: byte data[] = new byte[ 100 ]; receivePacket = new DatagramPacket( data, data.length ); // wait for packet socket.receive( receivePacket ); The client can send packets of data to the server using send method of the socket object When the client is done, close the socket connection . . Following is a simple UDP server that displays and echo datagram packets sent by a client: 7 import java.io.*; import java.net.*; public class DatagramServer extends Thread{ private DatagramPacket sendPacket, receivePacket; private DatagramSocket socket; public DatagramServer() { try { socket = new DatagramSocket( 5000 ); start(); System.out.println("Server waiting for connection"); while ( true ) { // set up packet byte data[] = new byte[ 100 ]; receivePacket = new DatagramPacket( data, data.length ); // wait for packet socket.receive( receivePacket ); // process packet System.out.println( "\nThe server has received:" + "\nFrom host: " + receivePacket.getAddress() + "\nHost port: " + receivePacket.getPort() + "\nLength: " + receivePacket.getLength() + "\nContaining:\n\t" + new String( receivePacket.getData(), 0, receivePacket.getLength() ) ); socket.send(receivePacket); } } catch( SocketException se ) { System.out.println(se.toString()); } catch( IOException io ) { System.out.println(io.toString()); } } public void run() { while(true) 8 { try { BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); String s = in.readLine(); byte data[] = s.getBytes(); sendPacket = new DatagramPacket( data, data.length, InetAddress.getLocalHost(), 4000 ); socket.send( sendPacket ); } catch ( IOException exception ) { System.out.println( exception.toString() ); } } } public static void main( String args[] ) { DatagramServer app = new DatagramServer(); } } And following is the source code for the client: import java.io.*; import java.net.*; public class DatagramClient extends Thread { private DatagramPacket sendPacket, receivePacket; private DatagramSocket socket; public DatagramClient() { try { socket = new DatagramSocket(4000); System.out.println("Cleint Started. Type a text to be send to the server"); start(); while ( true ) { 9 // set up packet byte data[] = new byte[ 100 ]; receivePacket = new DatagramPacket( data, data.length ); // wait for packet socket.receive( receivePacket ); // process packet System.out.println( "\nThe cleint has received:" + "\nFrom host: " + receivePacket.getAddress() + "\nHost port: " + receivePacket.getPort() + "\nLength: " + receivePacket.getLength() + "\nContaining:\n\t" + new String( receivePacket.getData(), 0, receivePacket.getLength() ) ); } } catch( SocketException se ) { System.out.println(se.toString()); } catch( IOException e ) { System.out.println(e.toString()); } } public void run() { while(true) { try { BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); String s = in.readLine(); byte data[] = s.getBytes(); sendPacket = new DatagramPacket( data, data.length, InetAddress.getLocalHost(), 5000 ); socket.send( sendPacket ); 10 } catch ( IOException exception ) { System.out.println( exception.toString() ); } } } public static void main( String args[] ) { DatagramClient app = new DatagramClient(); } } URL connections: Uniform Resource Locator provides a universal identification scheme that provide a common format of identifying resources on the Web. A URL provides 3 piece of information: the protocol used to transfer the data, (for example http, or ftp), the address of the host computer, and the path of the file that is located on the host computer. For example: http://www.hal.humberc.on.ca/~abdullah/index.html Java standard library provide services for connecting to remote site( web server) via HTTP or ftp request using the classes URL and URLConnection from the package java.net. To connect to a remote site, you need first to construct a URL object: URL url=new URL(protocol:resources); After you create the URL object, you want to obtain some data from the web server. There are two main ways to do this: reading directly from the URL object or obtain a URLConnection instance from it. URLConnection class make it easier to communicate with a web server without issuing an HTTP commands. To fetch the content from the web server , we use: InputStream in=url.openStream(); BufferedReader input=new BufferedReader(url.openStream()); String line=""; while ((line=input.readLine()) != null) 11 { System.out.println(line); } The class URLConnection provides additional information about the resources. URLConnection connection=url.openConnection(); connection.connect(); To read the web server response: BufferedReader in=new BufferedReader(new InputStreamReader(connection.getInputStream()); String line; while((line=in.readLine())!=null) { System.out.println(line); } To send data to the web server: PrintWriter ouput=new PrintWriter(connection.getOutputStream()); out.print(name1+"="+URLEncoder(value1) +"&" ); out.print(name1+"="+URLEncoder(value1) +"&" ); and so on. Another service provided by the java.net package is the conversion between a host name and an IP address using the class InetAddres. For example: InetAddress address=InetAddress.getByName("host"); byte[] addressByte=address.getBytes(); Examples: Ex1:Single client server chat application In this example we will build a client server chat application. The server will be able to server one client only. Both the client and the server need to be threaded 12 since both of them need to perform two separate tasks: sending messages, and receiving messages. Following is the source code for the server: import java.io.*; import java.net.*; public class SServerChat { public SServerChat() { try { final int PORT=9000; ServerSocket serverSocket= new ServerSocket(PORT); System.out.println("Server"); // wait for a client connection Socket socket = serverSocket.accept( ); // BufferedReader to read server input from the keyboard BufferedReader in = new BufferedReader (new InputStreamReader(System.in)); // PrintWriterObject to send messages to the client PrintWriter out = new PrintWriter (socket.getOutputStream()); System.out.println("A client has connected to the server, type a text and hit enter to chat or type exitChat to quit"); /* Separate thread for listening to the client messages and displaying them when they arrive */ receivingThread st=new receivingThread(new BufferedReader(new InputStreamReader(socket.getInputStream()))); st.start(); boolean done = false; // send the server messages while (!done) { String line = in.readLine(); if (line == null) done = true; else 13 { out.println("Server Says >>>" + line); out.flush(); if (line.trim().equals("exitChat")) done = true; } } socket.close(); } catch (Exception e) { System.out.println(e); } } class receivingThread extends Thread { BufferedReader input; public receivingThread(BufferedReader br) { input=br; } public void run() { try { String line = ""; // get messages from the client while ( (line = input.readLine() ) != null) { System.out.println("Client Says >>> " + line); } } catch (Exception e) { System.out.println(e.toString()); } } } public static void main(String[] args ) { 14 new SServerChat(); } } And following is the source code for the client: import java.io.*; import java.net.*; public class Client { public Client() { try { final int PORT=9000; Socket cs = new Socket("127.0.0.1",PORT); System.out.println("Client "); // BufferedReader object to read input from the keyboard BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) ); //PrintWriter object to send messages to the server PrintWriter output = new PrintWriter( cs.getOutputStream() ); /* Separate thread for listening to the server messages and displaying them when they arrive*/ receivingThread s=new receivingThread(new BufferedReader(new InputStreamReader(cs.getInputStream()))); s.start(); output.println("Client is connected"); System.out.println("You have connected to the server, ,type a text and hit enter to chat or type exitChat to quit"); output.flush(); // send messages to the server String line = in.readLine(); while (!line.equals("exitChat")) { 15 import java.io.*; import java.net.*; public class Client { public Client() { try { final int PORT=9000; Socket cs = new Socket("127.0.0.1",PORT); System.out.println("Client "); // BufferedReader object to read input from the keyboard BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) ); //PrintWriter object to send messages to the server PrintWriter output = new PrintWriter( cs.getOutputStream() ); /* Separate thread for listening to the server messages and displaying them when they arrive*/ receivingThread s=new receivingThread(new BufferedReader(new InputStreamReader(cs.getInputStream()))); s.start(); output.println("Client is connected"); System.out.println("You have connected to the server, ,type a text and hit enter to chat or type exitChat to quit"); output.flush(); // send messages to the server String line = in.readLine(); while (!line.equals("exitChat")) { output.println(line); output.flush(); line = in.readLine(); } cs.close(); } catch (Exception e) { System.out.println(e); 16 } } class receivingThread extends Thread { BufferedReader input; public receivingThread(BufferedReader r) { input=r; } public void run() { try { String line = ""; // receive messages from the server while ( (line = input.readLine() ) != null) { System.out.println(line); } } catch (Exception e) { } } } public static void main(String[] args ) { new Client(); } } Ex2:Multiple clients server chat application 17 We will enhance the server introduced in Ex1 to server multiple clients simultaneously. We will use an infinite loop to keep listening to incoming clients' requests. In order to keep track of the clients currently connected, we use a counter. Also we need a separate output stream for each connected client. Therefore we are using a vector to store an output stream object whenever a client is connected. To send messages to all the clients at the same time, we have to loop though the output stream vector and send the required message(s). Following is the source code for the server: import java.io.*; import java.net.*; import java.util.*; public class MServerChat extends Thread { Vector clientsOutput ; public MServerChat() { clientsOutput=new Vector(); try { final int PORT=9000; ServerSocket serverSocket = new ServerSocket(PORT); System.out.println("Waiting for incoming connections on port "+PORT +" .To quit, type exitChat"); // counter to keep track of the client number int count = 1; // start sending messages to the clients start(); while (true) { /* accept connections from clients. */ Socket incomingSocket = serverSocket.accept(); System.out.println("Socket connected."); PrintWriter output = new PrintWriter( incomingSocket.getOutputStream() ); /* add the PrintWriter object to the verctor clientsOutput. We will use this 18 vector to output messages to all connected clients */ clientsOutput.addElement( output ); // start receiving messages receivingThread rt= new receivingThread (incomingSocket.getInputStream(),count ); rt.start(); count++; } } catch (Exception e) { System.out.println(e.toString()); } } public void run() { try { BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) ); String line = in.readLine(); // broadcast the server messages to all connected clients. each client must have its own PrintWriter object while (!line.equals("exitChat")) { for (int i=0; i < clientsOutput.size(); i++) { PrintWriter output = (PrintWriter)clientsOutput.elementAt(i); output.println("Server Says >>>"+line); output.flush(); } line = in.readLine(); } System.exit(0); } catch(Exception e ) 19 { System.out.println("main thread"+e.toString()); } } private class receivingThread extends Thread { BufferedReader input; int count; public receivingThread(InputStream inputStream, int cnt) { input = new BufferedReader(new InputStreamReader( inputStream ) ); count=cnt; } public void run() { try { String line = ""; while ( (line = input.readLine() ) != null) { System.out.println( "Client "+count+" Says >>> "+line); } } catch (Exception e) {System.out.println(e.toString()); } } } public static void main(String[] args) { new MServerChat(); } } The client is the same as shown in Ex1. Ex3:Private chat client server application 20 In this example we will modify the client server application in Ex2 by building a GUI based server to broadcast messages privately. When a client connects to the server, it will be added to a combo box in the application. The server can response privately to a specific client, by selecting that client from the connected users combo box. In this example we will also use object streams instead of text based stream to send and receive messages between the client and the server. Following is the source code for the server: import java.io.*; import java.net.*; import java.util.*; import java.awt.*; import javax.swing.*; import java.awt.event.*; public class privateChatServer extends JFrame implements ActionListener { private Vector clientsOutput ; private JTextArea messageReceived; private JButton send, exit; private JComboBox clients; private JLabel enter, connectedUsers; private JTextField messageSent; public privateChatServer() { super ("Private chat"); Container c=getContentPane(); c.setLayout(new BorderLayout()); messageReceived=new JTextArea(); send=new JButton("Send"); exit=new JButton("Exit"); exit.addActionListener(this); send.addActionListener(this); clients=new JComboBox(); c.add(new JScrollPane(messageReceived),BorderLayout.CENTER); JPanel north=new JPanel(); connectedUsers=new JLabel("Connected Users"); north.add(connectedUsers); north.add(clients); c.add(north,BorderLayout.NORTH); JPanel south=new JPanel(); enter=new JLabel("Type a message"); messageSent=new JTextField(15); 21 south.add(enter); south.add(messageSent); south.add(send); south.add(exit); c.add(south,BorderLayout.SOUTH); setSize(450,400); setVisible(true); clientsOutput=new Vector(); try { final int port=9000; ServerSocket serverSocket = new ServerSocket(port); messageReceived.append("Waiting for incoming connections on port "+port +" .To quit, type exitChat\n"); // counter to keep track of the client number int count = 1; while (true) { /* accept connections from clients. */ Socket incomingSocket = serverSocket.accept(); ObjectOutputStream output = new ObjectOutputStream( incomingSocket.getOutputStream() ); /* add the ObjectOutputStraem the vector clientsOutput. We will use this vector to output messages to all connected clients */ clientsOutput.addElement( output ); // start receiving messages receivingThread rt= new receivingThread (incomingSocket.getInputStream(),count ); rt.start(); count++; } } catch (Exception e) { messageReceived.setText(e.toString()); } } public void actionPerformed(ActionEvent e) 22 { if (e.getSource()==exit) System.exit(0); else if (e.getSource()==send) { try { if (! messageSent.getText().equals("")) { int index=clients.getSelectedIndex(); ObjectOutputStream output = (ObjectOutputStream)clientsOutput.elementAt(index); output.writeObject("Server Says >>>"+messageSent.getText()); output.flush(); } } catch(Exception ex1 ) { messageReceived.setText(ex1.toString()); } } } public static void main(String[] args) { new privateChatServer(); } private class receivingThread extends Thread { ObjectInputStream input; int count; public receivingThread(InputStream inputStream, int cnt) { try { input = new ObjectInputStream( inputStream ); count=cnt; clients.addItem("Client"+count); } catch(Exception ex2) { messageReceived.setText(ex2.toString()); } } public void run() { try 23 { String line = ""; while ( (line = ((String)input.readObject()) ) != null) { messageReceived.append( "Client "+count+" Says >>> "+line+"\n"); } } catch (Exception ex3) { messageReceived.setText(ex3.toString()); } } }} Remember that both the client and the server must send and receive messages in the same format. Following is the source code for the client: import java.io.*; import java.net.*; public class privateChatCleint { public privateChatCleint() { try { Socket cs = new Socket("127.0.0.1",9000); System.out.println("Client "); // BufferedReader object to read input from the keyboard BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) ); //ObjectOutputStream to send messages to the server ObjectOutputStream output = new ObjectOutputStream( cs.getOutputStream() ); // start receving messages from the server receivingThread s=new receivingThread(new ObjectInputStream(cs.getInputStream())); s.start(); output.writeObject("Client is connected\n"); System.out.println("You have connected to the server, ,type a text and hit 24 enter to chat or type exitChat to quit"); output.flush(); // send messages to the server String line = in.readLine(); while (!line.equals("exitChat")) { output.writeObject(line); output.flush(); line = in.readLine(); } cs.close(); } catch (Exception e) { System.out.println(e); } } class receivingThread extends Thread { ObjectInputStream input; public receivingThread(ObjectInputStream r) { input=r; } public void run() { try { String line = ""; // receive messages from the server while ( (line = ((String)input.readObject() )) != null) { System.out.println(line); } } catch (Exception e) { } } } public static void main(String[] args ) { 25 new privateChatCleint(); } } Ex4:Browse.java In this example we will build a simple browser that can display plain text and HTML documents: import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; import javax.swing.*; import javax.swing.event.*; public class Browse extends JFrame { private JTextField enter; private JLabel url; private JPanel northPanel; private JEditorPane contents; private JButton go; public Browse() { super("Web Browser"); Container c=getContentPane(); url=new JLabel("Enter URL"); enter=new JTextField("http://www."); enter.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { getPage(e.getActionCommand()); } }); go=new JButton("Go"); go.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { getPage(enter.getText()); } 26 }); northPanel=new JPanel(); northPanel.setLayout(new BorderLayout()); northPanel.add(url,BorderLayout.WEST); northPanel.add(enter,BorderLayout.CENTER); northPanel.add(go,BorderLayout.EAST); c.setLayout(new BorderLayout(10,10)); c.add(northPanel,BorderLayout.NORTH); contents=new JEditorPane(); contents.setEditable(false); contents.addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if(e.getEventType()==HyperlinkEvent.EventType.ACTIVATED) getPage(e.getURL().toString()); } }); c.add(contents,BorderLayout.CENTER); setSize(500,500); show(); } private void getPage(String location) { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { contents.setPage(location); enter.setText(location); } catch(IOException e) { JOptionPane.showMessageDialog(this,"Error, could not find the specified URL","Bad URL",JOptionPane.ERROR_MESSAGE); } setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } public static void main(String args[]) { Browse br=new Browse(); br.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { 27 System.exit(0); }}); } } Ex5: The following is an applet that provides the user a tree view of the available hyperlinks. When the user selects a hyperlink from the tree nodes in the applet, the corresponding web page will be displayed in a separate window of the applet's browser. Following is the source code for the applet: import java.awt.*; import java.applet.*; import java.awt.event.*; import java.util.*; import java.net.*; import java.text.*; import javax.swing.*; public class tree extends JApplet { private JTree t; private JLabel lbt,lbb; private Date curDate; private Hashtable ht; private Color color; public void init() { Container c=getContentPane(); color=new Color(Integer.parseInt(getParameter("red")),Integer.parseInt(getParameter(" green")),Integer.parseInt(getParameter("blue"))); c.setBackground(color); ht=new Hashtable(); String[] str=new String[]{ "Humber College ","My Site ","WEBCT"}; String[] str1=new String[]{"Yahoo","Hotmail"}; lbt=new JLabel("Click on a link to access it's page"); lbb=new JLabel(); 28 DateFormat df = DateFormat.getDateInstance(); curDate=new Date(); lbb.setText(df.format(curDate)); ht.put("Main Links",str); ht.put("Extrra Links",str1); c.setLayout(new BorderLayout()); t=new JTree(ht); t.expandRow(0); t.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { String out=null; JTree jt=(JTree)e.getSource(); int clickrow=jt.getRowForLocation(e.getX(),e.getY()); { AppletContext b=getAppletContext(); try { URL newDoc1=new URL("http://www.humberc.on.ca"); URL newDoc2=new URL("http://www.acad.humberc.on.ca/~abdullah"); URL newDoc3=new URL("http://webct.humber.ca"); URL newDoc4=new URL("http://www.yahoo.com"); URL newDoc5=new URL("http://www.hotmail.com"); if(jt.getMaxSelectionRow() ==1) b.showDocument(newDoc1,"_Blank"); if (jt.getMaxSelectionRow() ==2) b.showDocument(newDoc2,"_Blankt"); else if(jt.getMaxSelectionRow() ==3) b.showDocument(newDoc3,"_Blank"); else if(jt.getMaxSelectionRow()==5) b.showDocument(newDoc4,"_Blank"); else if(jt.getMaxSelectionRow()==6) b.showDocument(newDoc5,"_Blank"); 29 } catch(MalformedURLException ex) {} } }} ); c.add(new JScrollPane(t),BorderLayout.CENTER); c.add(lbt,BorderLayout.NORTH); c.add(lbb,BorderLayout.SOUTH); } } To view the applet in a browser, we will create the following simple HTML page <html> <head> <title> Applet </title> </head> <body> <APPLET CODE = "tree.class" WIDTH = "450" HEIGHT = "200"> <PARAM NAME = "red" VALUE="255"/> <PARAM NAME = "green" VALUE="0"/> <PARAM NAME = "blue" VALUE="0"/> <b>My Courses </b> <br/> <ul> <li> <a href="cpan452.html" >Client Server CPAN 542</a> </li> <li> <a href="cpan320.html" >COBOL CPAN 320 </a></li> <li> <a href="cpan452.html" >Visual Basic CPAN 220 </a></li> </ul> </APPLET> </body> </html> Since this applet uses Java 2 features, the Java Runtime Environment (JRE) must be installed on the client machine . Internet explorer doesn't support newer versions of Java, therefore the Java plug-in developed by Sun Microsystems is 30 needed to add support for Java. To instruct the browser to lunch the java plug-in, we have to use the htmlconverter tool that comes as part of the JSDK. After you use the converting tool, your html file should look as follows: <html> <head> <title> Applet </title> </head> <body> <!--"CONVERTED_APPLET"--> <!-- HTML CONVERTER --> <OBJECT classid = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" codebase = "http://java.sun.com/products/plugin/autodl/jinstall-1_4windows-i586.cab#Version=1,4,0,0" WIDTH = "450" HEIGHT = "200" > <PARAM NAME = CODE VALUE = "tree.class" > <PARAM NAME = "type" VALUE = "application/x-java-applet;version=1.4"> <PARAM NAME = "scriptable" VALUE = "false"> <PARAM NAME = "red" VALUE="255"/> <PARAM NAME = "green" VALUE="0"/> <PARAM NAME = "blue" VALUE="0"/> <COMMENT> <EMBED type = "application/x-java-applet;version=1.4" CODE = "tree.class" WIDTH = "450" HEIGHT = "200" red ="255"/ green ="0"/ blue ="0"/ scriptable = false pluginspage = "http://java.sun.com/products/plugin/index.html#download"> <NOEMBED> <b>My Courses </b> <br/> <ul> <li> <a href="cpan452.html" >Client Server CPAN 542</a> </li> <li> <a href="cpan320.html" >COBOL CPAN 320 </a></li> <li> <a href="cpan452.html" >Visual Basic CPAN 220 </a></li> 31 </ul> </NOEMBED> </EMBED> </COMMENT> </OBJECT> <!-<APPLET CODE = "tree.class" WIDTH = "450" HEIGHT = "200"> <PARAM NAME = "red" VALUE="255"/> <PARAM NAME = "green" VALUE="0"/> <PARAM NAME = "blue" VALUE="0"/> <b>My Courses </b> <br/> <ul> <li> <a href="cpan452.html" >Client Server CPAN 542</a> </li> <li> <a href="cpan320.html" >COBOL CPAN 320 </a></li> <li> <a href="cpan452.html" >Visual Basic CPAN 220 </a></li> </ul> </APPLET> --> <!--"END_CONVERTED_APPLET"--> </body> </html> 32