Java Cookbook, Second Edition

Problem

You want to open a parallel port.

Solution

Use a CommPortIdentifier 's open( ) method to get a ParallelPort object.

Discussion

Enough of serial ports! Parallel ports as we know `em are an outgrowth of the "dot matrix" printer industry. Before the IBM PC, Tandy and other "pre-PC" PC makers needed a way to hook printers to their computers. Centronics, a company that made a variety of dot matrix printers, had a standard connector mechanism that caught on, changing only when IBM got into the act. Along the way, PC makers found they needed more speed, so they built faster printer ports. And peripheral makers took advantage of this by using the faster (and by now bidirectional) printer ports to hook up all manner of weird devices like scanners, SCSI and Ethernet controllers, and others via parallel ports. You can, in theory, open any of these devices and control them; the logic of controlling such devices is left as an exercise for the reader. For now we'll just open a parallel port.

Just as the SerialPortOpen program sets the port's parameters, the ParallelPortOpen program sets the parallel port access type or "mode." Like baud rate and parity, this requires some knowledge of the particular desktop computer's hardware. There are several common modes, or types of printer interface and interaction. The oldest is " simple parallel port," which the API calls MODE_SPP. This is an output-only parallel port. Other common modes include EPP (extended parallel port, MODE_EPP) and ECP (extended communication port, MODE_ECP). The API defines a few rare ones as well as MODE_ANY, the default and allows the API to pick the best mode. In my experience, the API doesn't always do a very good job of picking, either with MODE_ANY or with explicit settings. And indeed, there may be interactions with the BIOS (at least on a PC) and on device drivers (Windows, Unix). What follows is a simple example that opens a parallel port (although it works on a serial port also), opens a file, and sends it; in other words, a very trivial printer driver. Now this is obviously not the way to drive printers. Most operating systems provide support for a wide variety of printers (Mac OS and Windows both do, at least; Unix systems tend to assume a PostScript or HP printer). This example, just to make life simple by allowing us to work with ASCII files, copies a short file of PostScript. The intent of the PostScript job is just to print the little logo in Figure 12-2.

Figure 12-2. PostScript printer output

The PostScript code used in this particular example is fairly short:

%!PS-Adobe % Draw a circle of "Java Cookbook" % simplified from Chapter 9 of the Adobe Systems "Blue Book", % PostScript Language Tutorial and Cookbook % center the origin 250 350 translate /Helvetica-BoldOblique findfont 30 scalefont setfont % print circle of Java 0.4 setlinewidth % make outlines not too heavy 20 20 340 { gsave rotate 0 0 moveto (Java) true charpath stroke grestore } for % print "Java Cookbook" in darker outline % fill w/ light gray to contrast w/ spiral 1.5 setlinewidth 0 0 moveto (Java Cookbook) true charpath gsave 1 setgray fill grestore stroke % now send it all to the printed page showpage

It doesn't matter if you know PostScript; it's just the printer control language that some printers accept. What matters to us is that we can open the parallel port, and, if an appropriate printer is connected (I used an HP6MP, which supports PostScript), the logo prints, appearing near the middle of the page. Example 12-3 is a short program that again subclasses CommPortOpen, opens a file that is named on the command line, and copies it to the given port. Using it looks like this:

C:\javasrc\io\javacomm>java ParallelPrint javacook.ps Mode is: Compatibility mode. Can't open input stream: write-only C:\javasrc\io\javacomm>

The message "Can't open input stream" appears because my notebook's printer port is (according to the Java Comm API) unable to do bidirectional I/O. This is, in fact, incorrect, as I have used various printer-port devices that require bidirectional I/O, such as the Logitech (formerly Connectix) QuickCam, on this same hardware platform (but under Unix and Windows, not using Java). This message is just a warning; the program works correctly despite it.

Example 12-3. ParallelPrint.com

import java.awt.*; import java.io.*; import javax.comm.*; /** * Print to a serial port using Java Communications. * */ public class ParallelPrint extends CommPortOpen { protected static String inputFileName; public static void main(String[] argv) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { if (argv.length != 1) { System.err.println("Usage: ParallelPrint filename"); System.exit(1); } inputFileName = argv[0]; new ParallelPrint(null).converse( ); System.exit(0); } /* Constructor */ public ParallelPrint(Frame f) throws IOException, NoSuchPortException, PortInUseException, UnsupportedCommOperationException { super(f); } /** * Hold the (one-way) conversation. */ protected void converse( ) throws IOException { // Make a reader for the input file. BufferedReader file = new BufferedReader( new FileReader(inputFileName)); String line; while ((line = file.readLine( )) != null) os.println(line); // Finally, clean up. file.close( ); os.close( ); } }

Категории