Remote-control Java
Use VNCj to export your Java user interface to VNC viewers
Now that Windows XP supports desktop remote control over the network, we see a cycle close, a cycle that has been closing in on us for a long time. Remote control is not new. In fact, mainframe dumb terminals were nothing more than remote controls for a central computer. Minicomputers, like the VAX (Virtual Address eXtension), introduced more sophistication—with distributed terminal server networks—complicating the mainframe’s strict hierarchy of terminal controllers. In both cases, once you had access to a computer from a terminal, you connected to other computers in the corporate network using terminal emulation. With a host computer located on the other side of the planet, remote control suddenly became real power. Then ARPANet (Advanced Research Projects Agency Networks) became the Internet, and a small dumb terminal could connect you to the world. The last technological step occurred when personal computers became affordable, allowing dumb terminals to get smart. With the advent of graphical terminals, you could control your remote computer just as easily as the one in your office, with the only difference being sluggish performance.
However, network bandwidth developed into a pretty big issue. Transferring graphics from host to terminal worked fine within a LAN, but even corporate WANs couldn’t handle inter-site graphical remote control. Meanwhile, though, PCs became as cheap as smart terminals, and controlling a remote computer suddenly didn’t make much sense when you could get a decent one in the room.
But remote control did not die out. Companies discovered that providing every employee with a computer costs a fortune in maintenance. PC operating systems were still not “fire and forget;” they required constant tuning and fiddling just to keep everyday work going. Terminals seemed like a good idea again. Microsoft caught the drift and introduced Windows Terminal Server, which was nothing more than a clone of the old X terminal workhorse, with an updated market rationale. The final step brought remote control into the home. Over the past few years, high-speed connections to offices and homes have grown popular, and we now see many proprietary products moving in to fill the demand, allowing us to control our office or home computers from our cell phones.
That Microsoft actually entrusted remote control technology to us idiots at home (Remember, Microsoft has to give us user support too!) represented a triumph for a 20-year-old model. With any computer acting both as host and terminal, all you need is an Internet connection to access any computer anywhere in the world.
With all this excitement about remote-control power, you should have it too. This article introduces a free, 100 percent Java library, VNCj, and shows you how to use it to create remote controllable Swing, AWT (Abstract Windowing Toolkit), and other applications in Java that can be accessed by any VNC (Virtual Network Computing) viewer. VNC is a free, ultra-light, and popular remote-control system originally developed by the Olivetti Research Laboratory, which later became AT&T Laboratories Cambridge. Its tiny terminals, called viewers, have ported to almost any platform you’ve heard of, including a number of Java applets. With VNCj, users can access your Java service from PDAs, cell phones, and virtually all desktops. Via the pixel model (see below) and JNI (Java Native Interface), VNCj can even serve non-Java code.
Remote-controlled applications
Remote-controlled computers feature higher complexity than, say, remote-controlled TV sets or toasters. For example, from the beginning, remote control allowed many terminals to work simultaneously, which requires multitasking and security systems. Often these systems are designed into the operating system, which eases maintenance because you can manage all security privileges centrally. One disadvantage: If you provide access at the operating system level, someone could possibly hack out of his or her restrictions, which has occurred. Another problem is that the remote-control layer doesn’t always possess all the features we need. For example, not all operating systems support simultaneous multiple users or can communicate with our terminals.
Remote control at the application level can solve these problems. The worst security breach would represent a hack into the application itself; the system would remain safe. As for features, they can be designed for specific goals, while an operating system solution would have to be generic.
Writing a remote-controlled application in Java has many advantages. The first, obviously, is platform independence. You can run your application on any server, and users would be none the wiser. But Java also provides a strong development platform in its own right for remote-control solutions. You can create a full windowed interface with Swing and immediately export it remotely because Swing only uses lightweight, Java-generated components. Also, Java contains a powerful 2D graphics library that can work on a memory buffer to the terminals. Any additional products that work with Java graphics, such as geographic information systems (GIS) and 3D modeling, will work immediately.
If you haven’t considered it yet, designing your next application to support remote terminals features a benefit. If you read my previous JavaWorld article, “Launching into Java” (September 2000), you know that the two assets of Web browsing, for both consumers and service providers, are security and zero deployment. Remote control, like launching, shares these features, making it ideal for broad deployment. In fact, the two deployment methods could complement each other. Smart terminals would launch one version of your service, while dumb terminals would remotely control another version. The caveat is that graphical remote control heavily strains the server, which must process each user’s interface. For applications that normally have few concurrent users, such as management modules, remote control is ideal. And, if your environment is already terminalized, then users might come to expect all services to be available from their terminals. They’ll ask you why the newest service isn’t.
Remote-control Java with VNCj
VNCj supports six different models for serving Java to VNC viewers:
The Swing model
Because AWT must serve the lowest common denominator, writing Java’s powerful GUI (graphical user interface) in 100 percent Java made sense: it would be implemented entirely as lightweight AWT components. The side effect is that despite Swing’s ability to mimic the underlying operating system’s look and feel, Swing is an oddball on the desktop. It does its own thing, and whatever features it has are the ones specifically programmed into it. For users, this is plain weird. Desktop enhancements and modifications that work on native applications don’t work on Swing. For developers, Swing seems an unnecessary and overweight (despite being lightweight) duplication of functionality already there. But for remote-control users and developers, Swing is a blessing.
Because all Swing components are Java-generated, they can transmit immediately over the wire. With VNCj, you can create a JDesktop
, populate it with JInternalFrame
s, and send it to VNC viewers. Swing allows for a true virtual desktop. If that is what you want, breathe easy; VNCj requires nothing more than your current knowledge of Swing programming. Also, note that, because the components are never drawn on the screen, you can use any resolution or color model you wish, even if the server does not support such a graphical configuration. Terminals with lesser capabilities still have access to your service, because VNC must tone down the graphics to viewers’ requirements. Figure 1 illustrates the Swing model demo.
The AWT model
No, I’m not crazy. I know AWT is normally made of heavy components, but it doesn’t have to be. You can create your own AWT that uses your own AWT peers. That’s what VNCj does: it uses Swing lightweight components as peers. Wait, since Swing depends on AWT, wouldn’t this rip apart the fabric of the space-time continuum, ending existence as we know it? Not really. Remember, our Swing components are virtual. The AWT model is built on top of the Swing model, which is built on top of VNC. The model features no heavy components anywhere. You can design VNCj to run on a machine that lacks support for AWT (VNCj 1.0, though, still requires the underlying AWT for fonts). The AWT model provides compatibility with legacy code or platforms. However, for GUI functionality, go for the Swing model, which can do everything AWT can and much more. And, because of the piggybacking, the models look identical to the user, as Figure 2 shows.
The lightweight model
Your application might not need a windowed GUI or it might provide a GUI of your own design. No problem, because any lightweight component you create will immediately work with VNCj. You need only inherit java.awt.Canvas
, call getGraphics()
, and draw. You have full access to the Java 2D library and any library employing AWT graphics. The demo for this model, included in VNCj, creates a simple line-drawing canvas. Because the lightweight model allows shared sessions (a VNC feature), the canvas is immediately a shared whiteboard (although more work is required if you want to avoid mouse pointer fights). Figure 3 shows the lightweight model demo.
The pixel model
Let’s get AWT out of the picture. The pixel model gives you raw access to an array of pixels sent to the user, which means you do the drawing. But that might be exactly what you need. Using JNI, you can fill this array with non-Java code and let VNCj do the serving. This is as fast as VNCj can take you. The demo for this model is a seven-segment digital clock, drawn by filling in the pixel array. Figure 4 illustrates this demo.
The console model
Hey, if Swing can get away with emulating a desktop on a desktop, why not emulate a console with a GUI? This brilliant idea might not make any sense to you. Any platform that can run a VNC viewer can surely run Telnet. But can it really? If you have a VNC infrastructure set up already, running the tried-and-tested VNC viewer may simply prove easier than fiddling with the Telnet emulation parameters, which are inconsistent across Telnet client software. VNCj’s console model allows you to emulate a console to a VNC terminal. Weird, but straightforward, and it works. And here’s a perk: You can share the console among a few users, a task Telnet does not normally do. You might also want to check out another one of my projects, telnetj, which you can use to serve to Telnet clients. If your client serves both VNC viewers and Telnet, you are doubly covered. For a look at the console model, see Figure 5.
The RFB model
Support for RFB (Remote Frame Buffer), VNC’s wire protocol, is implemented as an independent library within VNCj. If even the pixel model is not raw enough for you, the RFB model will do the trick. This model’s demo uses the AWT Robot
class to serve a picture of the underlying desktop to the clients, mimicking the more common use of VNC: desktop remote control. This demo is really a toy; install a dedicated VNC server if you want that kind of functionality.
A remote planet?
I hope I’ve piqued your curiosity, but now let me cool you down a bit. Remote control can offer the perfect solution in many situations, but a major compromise in others. Remote control strains the network bandwidth and the server’s CPU, which is entirely unnecessary if the client can do the job itself. After all, with our terminal devices growing smarter and smarter, why not let them run the user interface? As more and more platforms enable Java, the real solution should be launching Java with JNLP (Java Network Launch Protocol). Designing an application to support JNLP is just as easy as using VNCj. So, until we achieve an ideal computing world, why not design for both?