Welcome!

Java IoT Authors: Liz McMillan, Yeshim Deniz, Elizabeth White, Zakia Bouachraoui, Pat Romanski

Related Topics: Java IoT

Java IoT: Article

Creating Newsfeeds Using Java Applets

Creating Newsfeeds Using Java Applets

The conventional way to present up-to-date information is to keep it on your Web site or a Web site you have some access to or control over so you can modify the information as needed. This article describes a way to create newsfeeds using Java applets so that the applet can be embedded anywhere in any page, and the applet distributor can keep the presented information up to date by modifying information on the site. Ways to extend the ability of the applet using CGI programming are also examined. This solves problems for theaters, clubs and other organizations that want their information on many pages but want to maintain it in just one spot. Establishments that want to distribute information about sales and events, and, of course, news organizations, can also benefit from distributing newsfeeds. This article also discusses a way to ensure that the information isn't loaded from cache (anticaching).

Conceptually, this applet connects back to the server and retrieves information - from a flat file or a script - as a stream of bytes that are cast to chars and appended to a StringBuffer. The toString() method in StringBuffer is called, and the resulting string is parsed to create a Vector containing the news and any other information returned by the server. When you want to use the applet as a newsfeed, you can permit other sites to embed the applet in their pages (using the CODEBASE="URL" attribute, with the URL being the directory on your server where the class files are, just as you can embed an image loaded from another server in another page, as shown in Figure 1). The applet then connects back to the server from which it was downloaded and gets the information, irrespective of the page in which it's embedded.

The Code
The source code for the applet, contained in the file newsfeed.java, is less than 300 lines, yet it contains all the functionality necessary to create a simple newsfeed. It uses Java 1.0 event handling to keep the event handling simple and to work with older browsers. To compile it using a JDK 1.1 compiler, you'll need to use deprecation: javac newsfeed.java -deprecation.

The included packages and classes are needed for painting (awt.*), storing information in a vector (Vector), parsing the information returned from the server (StringTokenizer), networking (net.*), input/output classes and required exceptions (io.*), and working with dates (Date).

The integer variables that have global scope within the class -speed, iHeight, iTimesThrough and iCurrentPosition -store the speed of the thread and the font height and keep track of the number of times the retrieved news has been presented and the current position in the list of news items. The initial value of iTimesThrough, 11, is explained in the paint() method. The Thread variable, called newsthread, is used to implement the Runnable interface. An Image object is used for the background image. The String objects - strCurrentString and strCurrentURL - are used to store the current news item and the associated URL. The boolean bCalledFromRun, if true, increments iCurrentPosition when paint() is called. The Vector veInformation is used to contain the news items retrieved from the server.

The class extends Applet and can be run either in a browser or in AppletViewer. Implementing Runnable permits the class to spawn and run in its own thread. To implement the Runnable interface, we need to implement start(), stop(), and run() methods (discussed below).

Unlike most applets, newsfeed doesn't override init(); all the initialization is done in the initialize() method. This method is called from paint() the first time that paint() is called and every 10 times thereafter to refresh the news.

The initialize() method is the key method of the applet. The Date object that's created is used to get the current time in milliseconds (stored in lUnique), which is used to circumvent caching (anticaching is discussed later in this article). The passed-in graphics object is used to draw a string indicating that the news is being downloaded and to get the font metrics, from which the font height is determined and stored in iHeight.

The strType variable stores the type of news that's going to be requested. This information is used only if a script will process the request. Setting iCurrentPosition and strCurrentURL variables to 0 and ".", respectively, clears them.

Listings 1 contains five examples of URLs that can be read from. If you're experimenting with the applet using AppletViewer, you'd include the file called news.txt in the same directory as the applet (the file format of the news file is discussed later) and then run the applet in AppletViewer. Remember, when running in a browser, an applet can generally connect back only to the server from which it was downloaded. The URL string to use depends on whether you're using a flat file or a script, and the sophistication of the script. If you're using a flat file, you'd use "/news/news.txt". The applet gets the host name using getCodeBase().getHost() and creates a URL with the returned host and the path "/news/news.txt". If the applet was downloaded from www.lithic.com and you used the path "/news/news.txt", the URL would be http://www.lithic.com/news/news.txt. The "?"+lUnique circumvents caching. You can, of course, use other paths and file names, but the file must be a publicly accessible ASCII file in the correct format. The last three examples of URL are scripts, discussed later in this article.

One problem in retrieving the current news is that the requested URL may be loaded from cache. This can be overcome by creating a unique URL each time, which can be done by including a unique number in the query string. One way to accomplish this is to include the current time in the query string. If the time between queries is greater than the resolution of the system clock, this should overcome the caching problem. Using a Date to get the current time in milliseconds and appending it to the query strings of the script URLs is an effective anticaching strategy. The same strategy can be used with URLs that are not scripts, because they generally ignore the query string (an HTTP server will generally serve the same page if you type in index.html or index.html?123). The key thing is to present the browser with a URL that is unique so it won't find it in cache.

After the URL object is instantiated, openStream() is called, which returns an InputStream for reading from that connection. The InputStream object is used to instantiate a DataInputStream, which we read from until we reach the end of file, represented by an EOFException. The bytes returned from the DataInputStream are cast to chars, then appended to a StringBuffer. The string representing the contents of the URL is recovered by using the toString() method in StringBuffer. This is a general-purpose method for creating a string from the content of a URL - if you try this using (String)url.getContent(), you may get a ClassCastException. The vectorize() method takes the retrieved String and a token String as arguments and returns a Vector containing the news. In the information retrieved from the file or script, we expect the zeroth line - which becomes the zeroth node in veInformation - to be the name of an image stored in the codebase. After this image name is stored in strImage, the zeroth is removed, leaving as many nodes in the Vector as there are news items. After the image is loaded, the variable that tracks the number of times the new items have been presented is set to 0.

To simplify working with the information returned from the server, the vectorize() method creates a Vector from it. The two parameters passed in are the String to parse and the String on which to tokenize it. If the String to parse ended with the token used to parse, we'd end up with a final piece of zero length. To avoid this, if the string ends with the parse character, it's pulled off. Because most files or streams of bytes sent via a server are punctuated by a <cr><lf>, both are checked for and removed if they end the strIn. Most of the work is done using a stringTokenizer. After a Vector is instantiated, the stringTokenizer is instantiated with the string to parse on and the string to parse. In our model the string to parse on is always a new line, but passing in the string to parse on makes the method more flexible. The code then tokenizes the string, adding each token to the Vector.

The code that handles tokenizing by "\n" checks to see if a \r or \n is present and pulls them off the end of each token (they're assumed to be on the end; if your code needs these characters for anything, you may need to modify this code). The Vector is then trimmed to size and returned.

The paint() method, which is called repeatedly from run(), is used as the engine of this applet. The size of the applet is determined first, to be used to clear the applet's graphics context. If this is the first time through (iTimesthrough variable is initially set to 11, so initialize() will be called the first time through paint()), or if the number of times the news has been presented exceeds some arbitrary number of times (here 10), the news is refreshed using the initialize() method.

If an image is available, it's drawn on the background. The text is offset 45 pixels to be to the left of the image (it could also be drawn on top of the image). The examples in Figures 2 and 3 are just names for a company or club, but in practice they could be an advertisement or something associated with the news item. The image name is downloaded with the news, so it can be changed with each refresh.

Each line of news is in two parts: the URL is everything up to the first space, and the news item is everything after. After the current line of news is retrieved, the iCurrentPosition variable is incremented if bCalledFromRun is true. Initially the paint method is called repeatedly as the background image is drawn. To prevent an initial race through the news, the current position increments only if the paint() method was called from run(). New news is then drawn, in blue, 45 pixels from the left side of the applet and iHeight down (the iHeight variable was set to the font height in the initialize() method). Checking on whether the iCurrentPosition variable is bigger than veInformation, the Vector, which holds all the news items, permits the news to "wrap" back to the first news item if the current news item is the last. The iTimesThrough variable is incremented if the news wrapped, tracking the number of times that the current news has been displayed.

The mouseDown(), mouseEnter() and mouseExit() methods work together to create a mouse interface for the applet. In mouseDown(), if the current URL (set in paint()) isn't a ".", a URL object is instantiated and passed to the showDocument() method in the applet context for this applet. Using a "." permits presenting news items for which there is no link. The mouseEnter() method draws the current news item in red and shows the link in the status bar with showStatus(), both of which are common in applets that show menus or image maps. The thread is stopped in mouseEnter() so the current news item will remain displayed. The mouseExit() method undoes what the mouseEnter() method did by converting the text color back to blue, clearing the status and then starting the thread again.

The start(), stop() and run() methods are used to implement the runnable interface. A Thread object called newsthread is instantiated and started in the start() method. The run() method is called repeatedly, and the thread is paused for speed milliseconds; then repaint() is called. The stop() method is called when the applet stops.

To update the news in real time, just upload a new flat file or change the data in the database if you're using a database with a script. Flat files can also be changed by using CGI scripts that allow an authenticated user to modify, delete or add to the contents of the flat file. The next time the applet accesses the flat file or script, it'll get the current information (sometimes flat files are cached by the server, but in our experience this hasn't been a problem).

Working with CGI Scripts vs Flat Files
Whether using a flat file, a CGI script that uses a flat file for data or a CGI script that uses a DSN and a database, the applet expects the data to be presented in a certain format:

line1: Image<optional \r><\n >
line2: URL1[space]Text for news item 1<optional \r><\n >
line3: URL2[space]Text for news item 2<optional \r><\n >
.
.
.
Line: URLn-1[space]Text for news item n-1<optional \r><optional \n>

Any data source that can supply text in this format can act as a data source for the newsfeed. In practice, the designer would probably choose something with more flexibility and capability, but this works fine for our example. In any case, if you use a flat file, remember to upload it using ASCII mode.

The news.txt file has information in the format above, so it can be parsed directly by the applet. The information in cginews.txt must be supplied to the applet via newsfeed.pl, a Perl script. If you use the script and the cginews.txt, be sure that the permission of the script is executable, the path to the Perl interpreter is correct and the cginews.txt is world readable. Note that \n is read from the cginews.txt file; if the terminal character on each line is not a \n , the information won't parse correctly when it's received by the applet. (Perl programming is beyond the scope of this article, but if you have some experience, these scripts should be a starting point. If not, the flat file can provide most of the same functionality.)

The Perl script newsfeed.pl first retrieves the query string (this is what's after the "?"). If the URL accessed was http://www.lithic.com/cgi-local/newsfeed.pl?ls930353830, the query string would be ls930353830. The numbers after the Is represent the anticaching strategy discussed above. The first two characters are passed to the PrintNews function, which prints characters 2 through the last character of every line in the cginews.txt file that start with these two letters.

In the example case the two letters are "ls". The first two characters of each line, which are the code compared to the type passed in, are removed before the line is printed. Using a code permits a single applet with a single data source to supply different news depending on the query string. This could be combined with cookies on the page the applet was embedded in, so user preferences could dictate what news was sent.

A guardian is set so that if no lines were printed for a given two-letter combination, a "." and a line indicating there was no news would be printed out.

Modifications to the Perl script and minor modifications to the applet would permit a more sophisticated interaction with the user. For example, if the URL http://www.lithic,com/cgi-local/moresubstantialnewsfeed.pl?type=Is&docbase=[doc base]&time=[time] were constructed and opened, where [doc base] and [time] are understood to be the page that the applet is embedded in and the current time, and the information was parsed by the script, the type and codebase would be known (knowing the codebase would permit returning an appropriate message to unauthorized newsfeeds, rather than the news). The time is still used for anticaching, but it may also be interesting statistically.

Conclusion
The newsfeed is easy to set up and distribute, but if you have some difficulty, here are some things to check.

  • In the newsfeed.java, did you choose the right string for the URL (for example, if you have a news.txt in a feed directory, make sure you create a string that points at /feed/news.txt)?
  • Check if the URL creation code was changed to url=new URL(str) (this is indicated in comments in the code).
  • Did you upload the news file in ASCII mode and the class files in binary mode?
  • You should use the Perl script only if you have some experience with Perl.
  • You may want to remove the ?=code after the .txt if you're using a flat file and having problems.

This implementation of a newsfeed, though limited, created a very small class file that displays news, responds to button clicks when there is a link associated with a news event, and circumvents caching. Many improvements are possible: adding more colors, offsets, speed, audio clips and so forth. Additionally, double buffering would offer smoother graphics. The applet offers a functional framework in a small package.

Using a newsfeed solves many of the problems associated with the static nature of Web pages and solves access issues. For example, a document on a CD-ROM could present current information (provided that the person reading the HTML document in which the newsfeed was embedded was attached to the Internet). Used correctly, newsfeeds based on the applet described in this article can be a way to make the net more relevant, provide better service to your customers and substantially decrease the time it takes to disseminate information.

More Stories By John Keogh

John Keogh is president of Lithic Software Corporation, an Internet software and services company. He has a background in computer science, chemistry and technical writing. John programs in C, C++, Java, Perl, SQL and several other languages.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
SYS-CON Events announced today that Silicon India has been named “Media Sponsor” of SYS-CON's 21st International Cloud Expo, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Published in Silicon Valley, Silicon India magazine is the premiere platform for CIOs to discuss their innovative enterprise solutions and allows IT vendors to learn about new solutions that can help grow their business.
We are seeing a major migration of enterprises applications to the cloud. As cloud and business use of real time applications accelerate, legacy networks are no longer able to architecturally support cloud adoption and deliver the performance and security required by highly distributed enterprises. These outdated solutions have become more costly and complicated to implement, install, manage, and maintain.SD-WAN offers unlimited capabilities for accessing the benefits of the cloud and Internet. ...
Founded in 2000, Chetu Inc. is a global provider of customized software development solutions and IT staff augmentation services for software technology providers. By providing clients with unparalleled niche technology expertise and industry experience, Chetu has become the premiere long-term, back-end software development partner for start-ups, SMBs, and Fortune 500 companies. Chetu is headquartered in Plantation, Florida, with thirteen offices throughout the U.S. and abroad.
SYS-CON Events announced today that CrowdReviews.com has been named “Media Sponsor” of SYS-CON's 22nd International Cloud Expo, which will take place on June 5–7, 2018, at the Javits Center in New York City, NY. CrowdReviews.com is a transparent online platform for determining which products and services are the best based on the opinion of the crowd. The crowd consists of Internet users that have experienced products and services first-hand and have an interest in letting other potential buye...
Business professionals no longer wonder if they'll migrate to the cloud; it's now a matter of when. The cloud environment has proved to be a major force in transitioning to an agile business model that enables quick decisions and fast implementation that solidify customer relationships. And when the cloud is combined with the power of cognitive computing, it drives innovation and transformation that achieves astounding competitive advantage.
DXWorldEXPO LLC announced today that "IoT Now" was named media sponsor of CloudEXPO | DXWorldEXPO 2018 New York, which will take place on November 11-13, 2018 in New York City, NY. IoT Now explores the evolving opportunities and challenges facing CSPs, and it passes on some lessons learned from those who have taken the first steps in next-gen IoT services.
Cloud-enabled transformation has evolved from cost saving measure to business innovation strategy -- one that combines the cloud with cognitive capabilities to drive market disruption. Learn how you can achieve the insight and agility you need to gain a competitive advantage. Industry-acclaimed CTO and cloud expert, Shankar Kalyana presents. Only the most exceptional IBMers are appointed with the rare distinction of IBM Fellow, the highest technical honor in the company. Shankar has also receive...
DXWorldEXPO LLC announced today that ICOHOLDER named "Media Sponsor" of Miami Blockchain Event by FinTechEXPO. ICOHOLDER gives detailed information and help the community to invest in the trusty projects. Miami Blockchain Event by FinTechEXPO has opened its Call for Papers. The two-day event will present 20 top Blockchain experts. All speaking inquiries which covers the following information can be submitted by email to [email protected] Miami Blockchain Event by FinTechEXPOalso offers sp...
DXWordEXPO New York 2018, colocated with CloudEXPO New York 2018 will be held November 11-13, 2018, in New York City and will bring together Cloud Computing, FinTech and Blockchain, Digital Transformation, Big Data, Internet of Things, DevOps, AI, Machine Learning and WebRTC to one location.
@DevOpsSummit at Cloud Expo, taking place November 12-13 in New York City, NY, is co-located with 22nd international CloudEXPO | first international DXWorldEXPO and will feature technical sessions from a rock star conference faculty and the leading industry players in the world. The widespread success of cloud computing is driving the DevOps revolution in enterprise IT. Now as never before, development teams must communicate and collaborate in a dynamic, 24/7/365 environment. There is no time t...