JavaApplet used to print over Serial Port

What I want to share with you today is a way to print on a serial printer (in my case I used a barcode printer).

Anyone is starting reading this post could thik: "Yes but is not too difficult to use serial port with Java". Yes but you have to think to another point: we are talking of a web-application and, our printer, is linked to the client (naturally... maybe my server is not directly accessible). And another interesting point is that our installed JRE could blocked the access to computer ports. I say "could" but it surely does if you haven't set the "policy" file or add necessary library to the JRE.

Anyway... here you are my experience.

Starting Point
The starting point was locate the necessary libraries, and after some tests with official Sun javax.comm I've decided to use RXTX library because they sort out with all necessary to use them on all operating systems.

And now... all is very simple to do.

Applet
As I said before, we need "something" printed on client machine. So we surely need a simple applet, maybe hidden.

Inside init method you just need to initialize your ports.

@Override
public void init() {
try {
Enumeration portList = CommPortIdentifier.getPortIdentifiers();

if (portList.hasMoreElements()) {
this.portId = ((CommPortIdentifier) portList.nextElement());
}
} catch (Exception e) {
e.printStackTrace();
}

//Opening port to test
try {
CommPort serialPort = this.portId.open("SerialPort", 200);
serialPort.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}


The second part of this code Opening port to test is necessary to let your applet always ready to print. During my tests if I didn't try to open the serial port after getting it sometime it does not work.


After this thing, what you need is a simple method to print what you need. I post here my code that, as I said, is used to print a barcode.

public void printBarCode(String code) {
try {
CommPort serialPort = this.portId.open("SerialPort", 200);

PrintStream out = new PrintStream(serialPort.getOutputStream(), true);
out.println("N\n");
out.println("D13\n");
out.println("S2\n");
out.println("B240,2,0,K,4,5,83,B,\"" + code + "\"\n");
out.println("P1\n");

out.close();

serialPort.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}


All information I'm sending to print was getting from EPL print manual. Are just information you need to set-up printer, page and barcode style.

If you need anything special you can consider your applet ready to use. You may just package it in a jar and add the jar to your webserver / web-application.

Adding applet to a page
Inside your page you can just add the applet using applet tag or object tag. In my case I have used applet one because the object give me some problems. In all tests I've done with applet works correctly both on IE and Firefox with windows and Linux.

<applet name="barcodeprinter" 
id="barcodeprinter"
archive="/BarCodeApplet.jar"
code="com.bytecode.priterapplet.BarCodePrinter"
MAYSCRIPT="true"
style="width: 1px; height: 1px; background: white;">
</applet>


Note the mayscript parameter. Is used to let your browser (javascript) to interact with your applet. In fact if you don't add it what you can do is just load a page with an applet that starts printing a "static text". Not so useful!

More interesting is sure letting the user the selection of the "code" to print. And you can make this with a very simple javascript code.

<script type="text/javascript">
function inventario(code) {
var applet = document.getElementById("barcodeprinter");
if(code != '') {
applet.printBarCode(code);
}
}
</script>


And to call your javascript

<a href="#" onclick="inventario('selectedCode');">Selected Element</a>


Configuring client
If you will try to use your applet without setting your JRE you couldn't print anything. What you need is just get RXTXcomm.jar to copy in JRE_HOME/lib/ext folder, and the correct library (DLL for Windows, .so for linux) and copy it in JRE_HOME/bin folder. For Mac the procedure is a little bit different but you can find the instruction for all operating system directly inside the file you have downloaded from RXTX website.

Enhancements
What I've tried after this thing is the dynamic configuration of the client. What you can do is copy the DLL/SO file in a client folder, load dynamically into JRE but, anyway, you have to set, at least, the .policy file on the client. Is a security setting made inside Java: from a webapplet you can't doing what you want on a client computer.

Anyway here you are a little example of what I've done

if (System.getProperty("os.name").toUpperCase().contains("WINDOWS")) {
libraryName = DLL_SERIAL_NAME;
libraryFile = System.getProperty("java.io.tmpdir") + DLL_SERIAL_NAME;
} else if (System.getProperty("os.name").toUpperCase().contains("LINUX")) {
if (System.getProperty("os.arch").contains("i386")) {
libraryName = SO_SERIAL_NAME_32;
} else {
libraryName = SO_SERIAL_NAME_64;
}

char fileSeparator = System.getProperty("file.separator").charAt(0);
libraryFile = System.getProperty("java.io.tmpdir") + fileSeparator + SO_SERIAL_NAME;
}

if (!(verifyLibraryExistence(libraryFile))) {
copyResourceFromJar(libraryFile, libraryName);
}
try {
System.load(libraryFile);
} catch (Exception e) {
e.printStackTrace();
}


DLL and so files are contained in the applet JAR.

Hope to be useful to anyone. And write to me if you have any kind of problem!