B4J Question Printing to USB Label printer

Declan

Well-Known Member
Licensed User
Longtime User
I am using the jFX8Print Library Version 0.7
I am using a Xprinter XP-365B Thermal Label printer.
My Label size is 39mm(W) X 18mm(H)
On my Windows 10 PC, the Xprinter is set as "Default Printer"
The Printer Preferences has only 1 paper size set - 39mm(W) X 18mm(H)
The printer works great and I have tested it with the Xprinter Test software.
My B4J app has a Panel "pnlQR" which has 2 X imageviews and 2 X labels.
The imageviews display the QR Barcodes, the labels display a text.
I use:
B4X:
    Dim m As Image = MainForm.RootPane.Snapshot
    Dim cv As Canvas
    cv.Initialize("")
    cv.DrawImage(m,0,0,100,60)
to take a snapshot of pnlQR.
I must then send this to the printer with btnPrint_Click (No Dialogs):
B4X:
Private Sub btnPrint_Click
    Dim m As Image = MainForm.RootPane.Snapshot
    Dim cv As Canvas
    cv.Initialize("")
    cv.DrawImage(m,0,0,100,60)
  
    Dim P As Printer = Printer_Static.GetDefaultPrinter
'    Dim P As Printer = GetPrinter("Xprinter XP-365B")
    Dim PA As PrinterAttributes = P.GetPrinterAttributes
  
    Dim p_paper As Paper = PA.GetDefaultPaper
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob2(p)
    pl = p.CreatePageLayout(p_paper,"PORTRAIT",1,1,1,1) ' You should change orientation and margin If Neccessary
  
    PJ.GetJobSettings.SetCopies(1)
    PJ.GetJobSettings.SetPageLayout(pl)
    PJ.GetJobSettings.SetPrintQuality("HIGH")
    PJ.GetJobSettings.SetJobName("QR_PRINTER")
  
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob2(P)
    PJ.PrintPage(pnlQR)
    PJ.EndJob
  
End Sub

However, I have the following error:
B4X:
Waiting for debugger to connect...
Program started.
Error occurred on line: 35 (Paper)
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:132)
    at b4j.example.printer._createpagelayout(printer.java:80)
    at b4j.example.main._btnprint_click(main.java:143)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:629)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:109)
    at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
    at anywheresoftware.b4a.BA$1.run(BA.java:234)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:186)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
    at com.sun.prism.j2d.print.J2DPrinter.getMediaSizeName(J2DPrinter.java:832)
    at com.sun.prism.j2d.print.J2DPrinter.printableArea(J2DPrinter.java:848)
    at javafx.print.Printer.createPageLayout(Printer.java:349)
    ... 28 more
Picked up _JAVA_OPTIONS: -Djava.net.preferIPv4Stack=true
If I send this to the printer with btnReprint_Click (With Dialogs):
B4X:
Private Sub btnReprint_Click
    Dim m As Image = MainForm.RootPane.Snapshot
    Dim cv As Canvas
    cv.Initialize("")
    cv.DrawImage(m,0,0,100,60)

    Dim P As Printer = Printer_Static.GetDefaultPrinter
'    Dim P As Printer = GetPrinter("Xprinter XP-365B")
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob2(P)
    PJ.ShowPageSetupDialog(Null)
    PJ.ShowPrintDialog(Null)
    PJ.PrintPage(pnlQR)
    PJ.EndJob

End Sub
I receive the following error:
B4X:
Waiting for debugger to connect...
Program started.
Error occurred on line: 67 (PrinterJob)
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:132)
    at b4j.example.printerjob._showpagesetupdialog(printerjob.java:105)
    at b4j.example.main._btnreprint_click(main.java:200)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:629)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:109)
    at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
    at anywheresoftware.b4a.BA$1.run(BA.java:234)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:186)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
    at com.sun.prism.j2d.print.J2DPrinter.getMediaSizeName(J2DPrinter.java:832)
    at com.sun.prism.j2d.print.J2DPrinter.printableArea(J2DPrinter.java:848)
    at javafx.print.Printer.createPageLayout(Printer.java:249)
    at javafx.print.Printer.getDefaultPageLayout(Printer.java:221)
    at javafx.print.JobSettings.pageLayoutProperty(JobSettings.java:1097)
    at javafx.print.JobSettings.getPageLayout(JobSettings.java:1133)
    at com.sun.prism.j2d.print.J2DPrinterJob.syncPageLayout(J2DPrinterJob.java:615)
    at com.sun.prism.j2d.print.J2DPrinterJob.syncSettingsToAttributes(J2DPrinterJob.java:564)
    at com.sun.prism.j2d.print.J2DPrinterJob.showPageDialog(J2DPrinterJob.java:240)
    at javafx.print.PrinterJob.showPageSetupDialog(PrinterJob.java:343)
    ... 28 more
Picked up _JAVA_OPTIONS: -Djava.net.preferIPv4Stack=true
I have attached my app ZIP file.
 

Attachments

  • Printer.zip
    15 KB · Views: 209
Last edited:

MicroDrie

Well-Known Member
Licensed User
As I wrote before, the advantage of a standard is that there are so many standards. We close the command line with sending a CRLF. However in B4X this is only a LineFeed (LF) character and the ESCPOS seems to close by default with the CRLF as Sseparator Of Data (SOD). What happens to this code?
Xprinter Commando file with Sseparator Of Data:
Sub txtInput_Action
    Dim SOD As String = Chr(13) & Chr(10)                ' Sseparator Of Data
    Dim strTx As String
    strTx = $"${Chr(27)}@"$    & SOD                        ' --- Reset printer
    strTx = strTx & "SIZE 39.00 mm,18.00 mm" & SOD
    strTx = $"${strTx}DIRECTION 0${SOD}"$                ' --- 0 or 1
'    strTx= strTx & "DIRECTION 1,0" & SOD
    strTx= strTx &"GAP 0 mm,0 mm" & SOD
    strTx= strTx &"CODEPAGE 850" & SOD
    strTx= strTx &"CLS" & SOD
    strTx = $"${strTx}QRCODE 37,13,H,4,N,0,"QRCODE1"${SOD}"$
'    strTx= strTx &"QRCODE 37,13,0,H,4,A,0," & Chr(34) & "QRCODE1" & Chr(34) & SOD
    strTx= strTx & "PRINT 1,1" & SOD
End Sub
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
As I wrote before, the advantage of a standard is that there are so many standards. We close the command line with sending a CRLF. However in B4X this is only a LineFeed (LF) character and the ESCPOS seems to close by default with the CRLF as Sseparator Of Data (SOD). What happens to this code?
Xprinter Commando file with Sseparator Of Data:
Sub txtInput_Action
    Dim SOD As String = Chr(13) & Chr(10)                ' Sseparator Of Data
    Dim strTx As String
    strTx = $"${Chr(27)}@"$    & SOD                        ' --- Reset printer
    strTx = strTx & "SIZE 39.00 mm,18.00 mm" & SOD
    strTx = $"${strTx}DIRECTION 0${SOD}"$                ' --- 0 or 1
'    strTx= strTx & "DIRECTION 1,0" & SOD
    strTx= strTx &"GAP 0 mm,0 mm" & SOD
    strTx= strTx &"CODEPAGE 850" & SOD
    strTx= strTx &"CLS" & SOD
    strTx = $"${strTx}QRCODE 37,13,H,4,N,0,"QRCODE1"${SOD}"$
'    strTx= strTx &"QRCODE 37,13,0,H,4,A,0," & Chr(34) & "QRCODE1" & Chr(34) & SOD
    strTx= strTx & "PRINT 1,1" & SOD
End Sub
Unfortunately, same result.
Only prints out the code
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Log the value of P after the Dim P As Printer = Printer_Static.GetDefaultPrinter line and p_paper after the Dim p_paper As Paper = PA.GetDefaultPaper line. to check there is a default printer and a default paper for that printer.

You can also use:

B4X:
Log(PA.GetSupportedPapers)

To see the papers available.
 
Last edited:
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Ok next trick by using the printer dump mode which print all the characters that are received by the printer. follow the following procedure:
  1. Switch the printer off and on
  2. Start the test software so that the QR code is printed out.
  3. Then put the printer in dump mode by switching the power off
  4. Make sure that the label roll is installed correctly and the printer top cover is closed
  5. Press and hold the PAUSE button and the FEED button, then turn on the power
  6. When the power indicator (blue light) and ERROR indicator (red light) light simultaneously, release buttons. The printer is changed to Dump Mode and print as below chart
    1653572963279.png

    Note: Printer wil not print if data is not more then one piece of label, and need to press FEED button to force the printer to print it out
  7. Repeat the same printer test again to send the characters to the printer
Let use known the printed dump charters to see what is sent to the printer.
 
Upvote 0
Top