Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News

SYS-CON.TV
Cloud Expo & Virtualization 2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Cloud Computing & Enterprise IT: Cost & Operational Benefits
How and Why is a Flexible IT Infrastructure the Key To the Future?
Click For 2008 West
Event Webcasts
Building a Chat Applet Part 2
Building a Chat Applet Part 2

Last month, we started a fun project in creating a chat room applet. The overall project illustrates how to create Perl scripts which will be used as back-ends for your Java applets. The Java applets will interact with the Perl program using a standard CGI interface. While you can have a lot of fun with this lightweight chat applet, my goal for you, however, is to look beyond this little applet and ask yourself, "How else can I use this method of sending data to a Web server, and process it on the Server side?". You can, for instance, use this to make a shopping cart, maintain data without using cookies, send a transaction to Cybercash (which uses Perl Scripts), etc.

This month, we will focus on the client-side Java applet. This is what the world will see as the chat room. To effectively do this, I have chosen to create an applet object and a Panel object. The applet will simply act as a container for the Panel object. The Panel object will then be the meat of the project.

The Chat class is derived from the applet Class. This class will be called by the HTML web page, which can contain parameters that the applet will extract. The parameters will be used to set the path to the Perl program and name of the log file. The log file, which gets created and maintained by the Perl Script, will reside on the Web server. In it, we will store the last ten chat submissions in order of most recent first.

The init() method of the Chat class will use the ternary operator as a method to extract the parameters in the HTML file. Normally, I never use the ternary operator for anything since it is sort of cryptic. I use it here, however, because it lends itself to this purpose. The init() method also makes an instance of the ChatPanel object which will actually contain the chat engine. After setting the applet's layout to BorderLayout, I have added the ChatPanel object to it in its Center position (see Listing 1).

The start() and stop() methods just call the ChatPanel object's start() and stop() methods, respectively. This will be important not only for starting and stopping the chat thread, but for sending a message to the Web server that the client has entered/exited the chat room.

public String getCGIPath(){
return cgiPath;
}

ChatPanel chatScreen;

Thread runner = null;
String chatLogFileName, cgiPath;
}

The ChatPanel class is quite complex. It implements Runnable, since we will use a Thread to refresh the chat data on our screen. This object will extend Panel, which we will configure as a CardLayout container. It will contain two additional Panels, one of which will gather setup information, such as the client's desired chat name, and the other will display the actual chat messages.

To construct this object, we will pass two parameters:

  • A handle to the applet
  • A String that will specify the file name of the chat log

    After initializing some instance variables, we construct the panels. To build them, I have opted to nest some additional components, such as Panels, instead of using GridBagLayout. Both the Setup and Chat panels use BorderLayout. This method adds the various AWT components needed to these panels using the standard add() method. After each Panel is constructed, we will add them to the card layout panel, which will contain them (see Listing 2).

    The start method checks to see if the user has entered a name. It the user has not entered a name to chat with, it will bring the setup panel to the front and request focus for the TextField, which will be where the user will enter a name. If the user has entered a name, we will create a new SubmitToChatServer object with a message indicating that this person has entered the chat room. On the same line, we start() that object, which will, in turn, spawn a new Thread to send that data to the chat server. Each line we send to the chat server will work exactly in this way, spawning a separate thread with which to send the data. Next, we will start our chat engine by creating another thread for it, if one does not already exist, and starting it. This will, in turn, invoke this object's run() method in the thread (see Listing 3).

    The stop() method will do a similar thing to what the start() method does. It will create another SubmitToChatServer object with a message indicating that the user has left the chat room and start the process of sending it in another thread. After doing so, it will stop the chat engine's thread so that we will not be constantly refreshing the screen.

    public void stop(){
    if(runner != null){
    new SubmitToChatServer("*** "+identity+"
    Has Left This Chat Room. ***",app, chatFileName).start();
    runner.stop();
    runner = null;
    }

    }

    The run() method will be the heart of the chat engine. The first thing we do is request focus on the TextField, which will be used for chat entry. The next part of this method required some thought and experimentation. Since the AWT's TextArea object does not wrap text to the next line when we have reached the right side of it, I needed to develop my own text wrapping technique. In order to do this, we need to figure out the width, in pixels, of the average character in a specific font. I did this by using a FontMetrics object for the chatArea. I determined the width of a string which contains the alphabet in upper and lower case. I have even included some spaces and periods. Then, I divided the length of this string by the number of characters in it. This gives me the average width, in pixels, of the text that users may type in. I can later compare this to the width of the Text area to determine how many characters will fit on a line. Once this is done, we go into an infinite while loop, which invokes a method called refresh() and pauses the thread for the length of time specified in refresh time (see Listing 4).

    As you may have guessed, the refresh() method will be used to refresh the chat data on the screen. It will be responsible for downloading the chat log file and parsing its information. First, it creates a URL object for the chat log file. Next, we create a DataInputStream object, which we will use to read its data. Since the log file stores its most recent data first, we will need to read each line and pre-pend it to the front of a temporary String, named chatData, which will be used to store the new data with the oldest data first. The first line we read (Most Recent Chat) will be stored for the next time this method is called. Each line read will need to be processed by the processText() method. This method will perform the wrapping of text if necessary. We will keep doing this on a line by line basis, until we read a line that matched the first line read from the previous iteration of this method. When finished, we will append the temporary String to the chatArea TextArea and close the stream. To force the TextArea to scroll down to the bottom, we will select the last character of text contained within it (see Listing 5).

    The processText() method is responsible for word wrapping within the TextArea. It takes the unprocessed text in as a parameter and returns the processed text as a String. If the text contains fewer characters than the average characters per line, then we will simply return the text with two new-line characters appended to it. If the text contains more characters than the average characters per line, then we examine the first group of characters that fit on a line. We count backwards until we find the last instance of a space. Here, we will insert a new-line character and repeat the process on the remaining text after we pre-pend the person's name, which we extract from the text, to the beginning of the remaining text. When finished, we return the completed processed text with two new-line characters appended to the end (see Listing 6).

    Since most browsers in use today do not support 1.1, I still use the 1.0 event model for applets. The handleEvent method is used for both the setup and chat panels. Here, we simply handle the action events for the buttons, as well as if the person generates an action event on a TextField (by pressing the enter key, for instance). If the target is the chatLine or the sendButton, we call the sendChat() method. If the target is the nameField or the setupButton, we need to check if they have actually entered a name. If not, we tell them to enter a name. If they have entered a name, we enter the chat room, show the chat panel and start the chat engine (see Listing 7).

    The sendChat() method simply creates a new SubmitToChatServer object with the text to be sent to the Perl Script. The text is a String constructed with the identity of the person and the text extracted from the chatLine TextField. We need to start the transfer, so we invoke the start() method on this object, which will send the chat line in a new Thread. Next, we need to clear the chatLine TextField.

    void sendChat(){

    new SubmitToChatServer(identity+" >:
    "+chatLine.getText(),app,chatFileName).start(); chatLine.setText("");

    }

    To finish off this class, I have written a number of accessor and mutator methods. These include:

    setRefreshTime()
    setIdentity()
    getIdentity()
    setChatLogName()

    I may use these methods later if I wish to be more elaborate in my applet class (see Listing 8).

    There may be a number of things you wish to do to optimize this Chat applet. For instance, you may want to move the refresh time up or down depending on your chat traffic. Remember, however, that you will be refreshing at longer or shorter intervals and each refresh will read the current log file, which stores up to twenty lines of chat. If you have heavy traffic in your chat room, more than twenty lines may have been submitted during that time period. You may want to alter the Perl Script to store more lines; however, twenty seem to be more than adequate in most situations.

    In addition, I have noticed that performance is drastically improved when using ISAPI Perl with IIS on Windows NT Server. You can download this for free at http://www.activestate.com. Note: You will need both the Win32 and ISAPI versions. The ISAPI version must be installed on top of the Win32 version. You may need to edit the registry, particularly in the scriptmap section under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters\Scriptmap. Here, you would want to make sure the Perl is registered to the file extensions .pl and .cgi. The .pl should be set to C:\Perl\bin\perlIS.dll and the .cgi should be set to C:\Perl\bin\Perl.exe %s %s. If you want to use the ISAPI version, rename your Perl Script's extension to .pl and make this modification in the Java program as well, where the Perl Script is referenced.

    Well, that's it. I hope you have had a lot of fun with this project. It demonstrates several exciting methods of interacting with a Web server and introduces many new possibilities for your applets.

    About Joseph DiBella
    Joseph M. DiBella is the Senior Java Instructor and Curiculum Developer for Computer Educational Services in New York City. He also is the President of HMJ Electronics, a computer consulting company which develops software and Java-enhanced Web sites.

  • In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    I'm a late comer ,and just caught part 2 on building a chat applet.Can anyone provide me with the whole tutorial on this subject? Thank you in advance.


    Your Feedback
    Perry Molter wrote: I'm a late comer ,and just caught part 2 on building a chat applet.Can anyone provide me with the whole tutorial on this subject? Thank you in advance.
    Latest Cloud Developer Stories
    Swisscom, the Swiss telecom, is going into the cloud business. Its subsidiary Swisscom IT Services AG has signed up with Red Hat as a Certified Cloud Provider and launched a public cloud Infrastructure-as-a-Service (IaaS) cloud targeting enterprise-class customers primarily in ...
    Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP)....
    In a surprise move on Tuesday, January 10, Oracle wheeled out its Big Data Appliance. That’s the one it said in October would be ready sometime in the first half. Only nobody believed it meant early in the first half. Heck, it’s not even clear anybody thought Oracle could make ...
    Rackspace Hosting, the service leader in cloud computing, on Thursday announced its acquisition of SharePoint911, an industry leader in SharePoint consulting, training, and "JumpStart" services within SharePoint. The unification of both companies provides capabilities to deliver ...
    CloudLinux, Inc., on Thursday released CafeFS 3, a virtualized file system for shared hosters that cages each customer within its own virtualized file system. CageFS becomes part of CloudLinux OS at no additional charge. CloudLinux OS, the only commercially-supported Linux OS m...
    Subscribe to the World's Most Powerful Newsletters
    Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

    SYS-CON Featured Whitepapers
    ADS BY GOOGLE

    Breaking Cloud Computing News

    BEACHWOOD, Ohio, Feb. 16, 2012 /PRNewswire/ -- DDR Corp. (NYSE: DDR) today announced operating re...