Simple Java Print App
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

We need a simple java app that takes input from a html tag and display the information below
Name: John Doe
Member: #123 Exp: 1/17/2018
then allows the user to click "Print" to send this information to a 2in x 1in label on a specific printer.

hey, can you please be more specific, and explain more what you want? if you are talking about HTML tags, the app need to be in JAVA or JavaScript?
Chlegou 9 months ago
it will be embedded into a webpage. The reason the App needs to be Java not Javascript is it needs to specify the printer, control the paper size, and send the print job. Javascript cannot control the printer in this way.
morepot 9 months ago
i don't know if this fits your case, but the datatables plugin, is very useful, to control webpages print actions. https://datatables.net/extensions/buttons/examples/print/index.html
Chlegou 9 months ago
Javascript cannot select a specific printer or control the paper size.
morepot 9 months ago
I'm afraid this can't be done serverside. Not sure though
gabrielsimoes 9 months ago
You can use Google Cloud Print https://developers.google.com/cloud-print/docs/appInterfaces And use the API in Javascript to apply actions.
Hasan Bayat 9 months ago
awarded to CyteBode

Crowdsource coding tasks.

4 Solutions

It's needs to specify the printer "Zebra Labels Gt420" and the paper size: 2in x 1in. To my knowledge, this cannot be done in javaSCRIPT. This is why I said Java.
morepot 9 months ago

Hi, maybe this works:
https://gist.github.com/Martin78b/4e6f68e5e4da00474c16e669c02fd88e

depending on how you integrate this to your solution
For the print button, may need to use javascript, something like this:
https://stackoverflow.com/questions/8545742/show-yes-no-confirmation-dialog-to-manipulate-the-data-in-the-database

You are in the correct direction. There are some compiler errors, it needs to set the Page Size and the input should not be an HTML file but input passed from the HTML file like this:
morepot 9 months ago

From what I gather, you need a Java applet running in a web page.

One problem is that most modern browsers do not allow running Java applets anymore. Only Internet Explorer on Windows and Safari on OS X seem to allow it.

Furthermore, the Java security settings need to be changed to add file:/// and possibly http://localhost (or the address of whatever server you want to host the web page on) in the "Exception Site List" section of the Security tab of the Java Control Panel. The user may also need to accept some security dialogs (e.g. "Allow blocked content" in Internet Explorer).

HTML Page

Save the following to an *.html file.

<!DOCTYPE html>
<html>
  <head>
    <title>HTML Form to Label Printer</title>
    <script type="text/javascript">
      function getPrinter() {
        return document.getElementsByName("printer")[0].value;
      }

      function getName() {
        return document.getElementsByName("name")[0].value;
      }

      function getMemberNo() {
        return document.getElementsByName("member-number")[0].value;
      }

      function getExpiration() {
        return document.getElementsByName("expiration")[0].value;
      }
    </script>
  </head>
  <body>
    <form>
      <input type="hidden" name="printer" value="Zebra Gk420t">
      <table>
        <tr>
          <td>Name:</td>
          <td><input type="text" name="name"></td>
        </tr>
        <tr>
          <td>Member #:</td>
          <td><input type="text" name="member-number"></td>
        </tr>
        <tr>
          <td>Expiration</td>
          <td><input type="text" name="expiration"></td>
        </tr>
      </table>
    </form>
    <p>
      <applet code="PrintApplet.class" height="40" width="200" mayscript="true">
      </applet>
    </p>
  </body>
</html>

Java Applet

In the same directory as the HTML file, save the following to a file called PrintApplet.java and run javac PrintApplet.java to compile it. You should end up with four *.class files. You will need the JDK to compile the applet.

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import java.util.*;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import netscape.javascript.JSObject;

class FormValues {
    public String name;
    public String memberNo;
    public String expiration;

    public FormValues(String name, String memberNo, String expiration) {
        this.name = name;
        this.memberNo = memberNo;
        this.expiration = expiration;
    }
}

class LabelPrinter implements Printable {
    PrintApplet pa;

    LabelPrinter(PrintApplet pa) {
        this.pa = pa;
    }

    public int print(Graphics g, PageFormat pf, int page)
        throws PrinterException {
        if (page > 0) {
            return NO_SUCH_PAGE;
        }

        Graphics2D g2d = (Graphics2D) g;
        g2d.translate(pf.getImageableX(), pf.getImageableY());

        FormValues fv = pa.readForm();
        g.drawString("Name: "     + fv.name,        0, 12);
        g.drawString("Member #: " + fv.memberNo,    0, 24);
        g.drawString("Exp.: "     + fv.expiration,  0, 36);

        return PAGE_EXISTS;
    }
}

class PrintAction implements ActionListener {
    PrintApplet pa;

    PrintAction(PrintApplet pa) {
        this.pa = pa;
    }

    public void actionPerformed(ActionEvent ae) {
        pa.disableButton();

        PrintService printService = pa.getPrinter();

        PrinterJob job = PrinterJob.getPrinterJob();

        PageFormat pf = job.defaultPage();
        Paper paper = pf.getPaper();

        double width  = 2.0 * 72; // 2"
        double height = 1.0 * 72; // 1"
        double margin = 0.2 * 72; // 0.2"

        paper.setSize(width, height);
        paper.setImageableArea(
            margin,
            margin,
            width  - (margin*2),
            height - (margin*2)
        );
        pf.setPaper(paper);

        Book book = new Book();
        book.append(new LabelPrinter(pa), pf);
        job.setPageable(book);

        PrintRequestAttributeSet printReqAttrs = new HashPrintRequestAttributeSet();
        printReqAttrs.add(new MediaPrintableArea(.2f, .2f, 1.6f, 0.6f, MediaPrintableArea.INCH));

        try {
            job.setPrintService(printService);
            job.print(printReqAttrs);
        } catch (PrinterException e) {
            e.printStackTrace();
        }

        pa.enableButton();
    }
}

public class PrintApplet extends Applet {
    private Button printButton;
    private PrintService  printerService = null;

    void disableButton() {
        printButton.setEnabled(false);
    }

    void enableButton() {
        printButton.setEnabled(true);
    }

    PrintService getPrinter() {
        return printerService;
    }

    FormValues readForm() {
        JSObject window = (JSObject) JSObject.getWindow(this);

        return new FormValues(
            (String) window.eval("getName()"),
            (String) window.eval("getMemberNo()"),
            (String) window.eval("getExpiration()")
        );
    }

    void findPrinter(String name) {
        PrintService[] printServices = PrinterJob.lookupPrintServices();

        for (PrintService printService : printServices) {
            String sPrinterName = printService.getName();
            if (sPrinterName.equalsIgnoreCase(name)) {
                printerService = printService;
            }
        }

    }

    public void init() {
        JSObject window = (JSObject) JSObject.getWindow(this);
        findPrinter((String) window.eval("getPrinter()"));
        if (printerService != null) {
            printButton = new Button("Print");
            this.add(printButton);
            printButton.addActionListener(new PrintAction(this));
        } else {
            this.add(new Label("Printer not found!"));
        }
    }
}

Then open the HTML file in Internet Explorer on Windows or Safari on OS X.

The label printer will need to be set as the default printer.

I do not own a label printer, so I could not test the code with a physical printer, but I tested it with the XPS printer in Windows 7 (a virtual printer that prints to files) and it successfully prints the label to a small 2" x 1" page.

Resulting print (XPS file converted to a 300 ppi PNG): https://i.imgur.com/nIlvhYL.png

Feel free to contact me if you need any changes made.

Edit 1: Added print image and cleaned up the code a little.

Edit 2: Added printer selection by hidden field.

Almost perfect! Needs to select the label printer too. One of the other attempts did this: for (PrintService printService : printServices) { String sPrinterName = printService.getName(); if (sPrinterName.equals("Zebra Labels Gt420")) { mPrinter = printService; bFoundPrinter = true; } } but I'm not sure that's the correct way to do it.
morepot 9 months ago
Yeah, that would fail if the printer name wasn't exactly "Zebra Labels Gt420". Do you want me to add a simple fuzzy search algorithm that takes the closest match as the printer? Also, isn't the model of the printer "GK240t"? I can't find anything about a Zebra Gt420.
CyteBode 9 months ago
Yes please. The printer is a "Zebra Gk420t" but I can fill in the exact name when I set it up on the computer it's for. It would be ideal to pass the printer name through a hidden input tag in the HTML: <input type="hidden" name="printer" value="Zebra Gk420t"
morepot 9 months ago
Okay, I can do that.
CyteBode 9 months ago
Hmm... I'm having some trouble with my installation of Java as I can't import anything from javax. Hold on while I look into that.
CyteBode 9 months ago
I've been using https://www.compilejava.net/ to compile the app and Firefox ESR to run it https://www.mozilla.org/en-US/firefox/organizations/ not sure if that helps you.
morepot 9 months ago
Thanks for the suggestion, but I actually found the problem (it was between the screen and the chair). I'm close to having something that works. It's just that the javax printing API isn't quite as lenient as the java one.
CyteBode 9 months ago
Okay, I've got something. I wasted some time trying to use javax.print.* directly, only to find out I could reuse most of my earlier code.
CyteBode 9 months ago
View Timeline