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: 215
Last edited:

MicroDrie

Well-Known Member
Licensed User
Ok now we are making progress because there is communication between the program and the printer. It print something that looks like the configuration. I couldn't find the printer commands on the Internet. however I found this picture:
1653113722701.png

Is there a printer switch in on the backside of the printer and in what position give the printer the configuration output on paper?

Do you have a document with the list of printer commands on the installation CD?
 
Upvote 0

Jones Hone

Active Member
Licensed User
Longtime User
I use the program you provided (Printer.zip). Did not modify any code.
I Use EPSON TM-T82II Receipt printer (USB PORT) to print.
Printing everything works fine!
43044.jpg
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Good to hear Jones that Steve Laming print program is working. There is an ESCPOS standard for label printers. The challenge is whether the label printer used follows that standard. In addition, if you accidentally give a printer a wrong command, the printer will "hang" in that command. Coincidentally, my daughter told me that her label printer prints 90 degrees rotated :eek:. I will investigate that and that is a great opportunity to test with a real label printer.
 
Upvote 0

keirS

Well-Known Member
Licensed User
Longtime User
You need to use a Generic / text only driver.
Good to hear Jones that Steve Laming print program is working. There is an ESCPOS standard for label printers. The challenge is whether the label printer used follows that standard. In addition, if you accidentally give a printer a wrong command, the printer will "hang" in that command. Coincidentally, my daughter told me that her label printer prints 90 degrees rotated :eek:. I will investigate that and that is a great opportunity to test with a real label printer.

ESC/POS is not a label printer standard it’s a receipt printer standard. There is no standard label printer language and there are quite a few of them as the printer manufacturers use their own languages. ZPL for Zebra, DPL for Datamax, IPlL for Intermec, TSPL for TSC and Krone, ESC \ Label for Epson etc. Some label printer manufacturers provide emulation for other label printer languages. ZPL is the most commonly emulated as Zebra is the biggest manufacturer. ESC \ Label is a partial emulation of ZPL The Xprinter emulates TSPL according to the Brochure.
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
Easiest way is to use the Serial port on the printer instead of the USB port and use the serial library. If you only have a USB port on the printer then it's slightly more tricky but usually doable.
Ok, I don't know if this is progress.
I have managed to setup my Xprinter on COM3
I am able to send text to the printer using jSerial:
B4X:
Sub txtInput_Action
    Dim strTx As String

    strTx= "SIZE 39.00 mm,18.00 mm" & CRLF
    strTx= strTx & "DIRECTION 1,0" & CRLF
    strTx= strTx &"GAP 0 mm,0 mm" & CRLF
    strTx= strTx &"CODEPAGE 850" & CRLF
    strTx= strTx &"CLS" & CRLF
    strTx= strTx &"QRCODE 37,13,0,H,4,A,0," & Chr(34) & "QRCODE1" & Chr(34) & CRLF
    strTx= strTx & "PRINT 1,1" & CRLF

    astream.Write(strTx.GetBytes("UTF8"))

End Sub
I know code is scrappy - but I get syntax errors if not as per above.
I am using an example of the code in post #13 by keirS
My printer outputs the text only and not the barcode.
I don't know if this is due to the TSPL required printer protocol?
 
Upvote 0

keirS

Well-Known Member
Licensed User
Longtime User
Ok, I don't know if this is progress.
I have managed to setup my Xprinter on COM3
I am able to send text to the printer using jSerial:
B4X:
Sub txtInput_Action
    Dim strTx As String

    strTx= "SIZE 39.00 mm,18.00 mm" & CRLF
    strTx= strTx & "DIRECTION 1,0" & CRLF
    strTx= strTx &"GAP 0 mm,0 mm" & CRLF
    strTx= strTx &"CODEPAGE 850" & CRLF
    strTx= strTx &"CLS" & CRLF
    strTx= strTx &"QRCODE 37,13,0,H,4,A,0," & Chr(34) & "QRCODE1" & Chr(34) & CRLF
    strTx= strTx & "PRINT 1,1" & CRLF

    astream.Write(strTx.GetBytes("UTF8"))

End Sub
I know code is scrappy - but I get syntax errors if not as per above.
I am using an example of the code in post #13 by keirS
My printer outputs the text only and not the barcode.
I don't know if this is due to the TSPL required printer protocol?
Do you mean it prints out the program? If so you need to change the printer driver to generic / text. See here as to why: https://support.honeywellaidc.com/s...er-with-a-Generic-Text-Only-driver-in-Windows
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
you need to change the printer driver to generic / text
Many Thanks,
I have changed the printer driver to generic / text:
PrinterPort.png

and set the printer Port to COM3.
I have printer a Test page and all Ok.
However, the COM port does to show in the "cmbPort" ComboBox.
I am using the following jSerial "Chat" code as a test:
B4X:
#Region  Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 400
#End Region

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim btnOpen As Button
    Dim cmbPort As ComboBox
    Dim txtInput As TextField
    Dim txtLog As TextArea
    Dim lblStatus As Label
    Private sp As Serial
    Private astream As AsyncStreams
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("1") 'Load the layout file.
    MainForm.Show
    MainForm.Title = "Bluetooth Chat"
    MainForm.BackColor = fx.Colors.White
    sp.Initialize("")
    cmbPort.Items.AddAll(sp.ListPorts)
End Sub

Sub cmbPort_SelectedIndexChanged(Index As Int, Value As Object)
    btnOpen.Enabled = Index > -1 'enable the button if there is a selected item
End Sub

Sub btnOpen_Action
    sp.Open(cmbPort.Value)
    astream.Initialize(sp.GetInputStream, sp.GetOutputStream, "astream")
    txtInput.Enabled = True
    btnOpen.Enabled = False
    lblStatus.Text = "Status: Open"
End Sub

Sub MainForm_Closed
    sp.Close
End Sub

Sub AStream_NewData (Buffer() As Byte)
    Dim s As String = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    LogMessage("You", s)
End Sub

Sub txtInput_Action
    Dim strTx As String

    strTx= "SIZE 39.00 mm,18.00 mm" & CRLF
    strTx= strTx & "DIRECTION 1,0" & CRLF
    strTx= strTx &"GAP 0 mm,0 mm" & CRLF
    strTx= strTx &"CODEPAGE 850" & CRLF
    strTx= strTx &"CLS" & CRLF
    strTx= strTx &"QRCODE 37,13,0,H,4,A,0," & Chr(34) & "QRCODE1" & Chr(34) & CRLF
    strTx= strTx & "PRINT 1,1" & CRLF

    astream.Write(strTx.GetBytes("UTF8"))
End Sub

Sub LogMessage(From As String, Msg As String)
    txtLog.Text = txtLog.Text & From & ": " & Msg & CRLF
    txtLog.SetSelection(txtLog.Text.Length, txtLog.Text.Length)
End Sub

Sub AStream_Error
    Log("Error: " & LastException)
    astream.Close
    AStream_Terminated
End Sub

Sub AStream_Terminated
    Log("Connection is broken.")
    lblStatus.Text = "Status: Close"
    txtInput.Enabled = False
    btnOpen.Enabled = True
End Sub
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
However, the COM port does to show in the "cmbPort" ComboBox.
Edit:
Com now showing in ComboBox.
When I run the above code, I get:
Label.jpg

So, communication with the printer appears to be fine.
There is something wrong with the syntax of the commands
 
Upvote 0

keirS

Well-Known Member
Licensed User
Longtime User
Edit:
Com now showing in ComboBox.
When I run the above code, I get:
View attachment 129472
So, communication with the printer appears to be fine.
There is something wrong with the syntax of the commands

Print 1,1 should be on a new line.

There is nothing wrong with the code. This is easily provable and I will show you how to replicate it using software available to you


1. I downloaded the printer driver from Seagull: https://www.seagullscientific.com/downloads/printer-drivers/xprinter-xp-365b/
2. I downloaded "Xprinter Special Edition BarTender Ultralite" from the Xprinter Website: https://www.xprintertech.com/xprinter-application
(Its the download called Label Printer App)
3. Installed the driver for the XP-365B.
4. From the downloaded RAR file for the Label Printer App, I installed the BarTender Software.
5. I ran the BatTender Software and selected New from the file menu.
6. I completed the Label Wizard as follows
edGmeubC.png

TQgAJFMc.png


gi7ohQaw.png

arzCdscF.png
Q7fgofEV.png


e9jtZRPU.png


7. Add a QR Code to the label:

GXEq7FKk.png


dZvHx57F.png


VEMeoUcZ.png


8. Right click the QR code and select properties an change the text to QRCODE1.

VbECZF1p.png


McFVnLK5.png



9. Select Print and and check the Print to File option.
PwVomHKk.png


10. Click on the Print Button and save to a text file. Then press the print button.

BShDSpzA.png


11. Open the save file in Notepad or other text editor:



These are the commands that are being sent to your XPrinter by the label software. I have my driver set to output the file port so I can save the file after the driver has processed it.

NJWDV3Tw.png


MTgSrkvE.png


Which produces the same code:

Ajrdb6U4.png
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
Ok,
Now when I run the following code:
B4X:
    Dim strTx As String

    strTx= "SIZE 37.7 mm,18 mm" & CRLF
    strTx= strTx & "DIRECTION 0,0" & CRLF
    strTx= strTx & "REFERENCE 0,0" & CRLF
    strTx= strTx & "OFFSET 0 mm" & CRLF
    strTx= strTx & "SET PEEL OFF" & CRLF
    strTx= strTx & "SET CUTTER OFF" & CRLF
    strTx= strTx & "SET TEAR ON" & CRLF
    strTx= strTx &"CLS" & CRLF
    strTx= strTx &"GAP 0 mm,0 mm" & CRLF
    strTx= strTx &"QRCODE 200,137,L,4,A,180,M2,S7," & Chr(34) & "QRCODE1" & Chr(34) & CRLF
    strTx= strTx &"CODEPAGE 1252" & CRLF
    strTx= strTx &"TEXT 214,32," & Chr(34) & "3" & Chr(34) & ",180,1,1," & Chr(34) & "QRCODE1" & Chr(34) & CRLF
    strTx= strTx & "PRINT 1,1" & CRLF

    astream.Write(strTx.GetBytes("UTF8"))
I get:
Label.jpg

Only the Text is printing.
Could it be something to do with the
B4X:
astream.Write(strTx.GetBytes("UTF8"))
I cannot find a way to write the .txt file to the com port
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
Try printing the label to your printer from the label software. What happens?
Using the label software "...BarTender UltraLite" and following your example, I get exactly the same output with print to file.
However, when I attempt to print directly to the printer, the printer prints out the text code as in post #52
 
Last edited:
Upvote 0

MicroDrie

Well-Known Member
Licensed User
I'm still waiting for a printer to test in real, but you can try the following modification:
Modified for printer:
Sub txtInput_Action
    Dim strTx As String
    strTx = $"${Chr(27)}@"$                                            '--- First reset printer
    strTx = strTx & "SIZE 39.0 mm,18.0 mm" & CRLF
    strTx = $"${strTx}DIRECTION 0${CRLF}"$                            ' --- Try 0 or 1
'    strTx= strTx & "DIRECTION 1,0" & CRLF
    strTx= strTx &"GAP 2 mm,2 mm" & CRLF                           ' --- Stay away from the paper edge
'    strTx= strTx &"GAP 0 mm,0 mm" & CRLF
    strTx= strTx &"CODEPAGE 850" & CRLF
    strTx= strTx &"CLS" & CRLF
    strTx = $"${strTx}QRCODE 37,13,H,4,N,0,"QRCODE1"${CRLF}"$
'    strTx= strTx &"QRCODE 37,13,0,H,4,A,0," & Chr(34) & "QRCODE1" & Chr(34) & CRLF
    strTx= strTx & "PRINT 1,1" & CRLF
    astream.Write(strTx.GetBytes("UTF8"))
End Sub
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
I'm still waiting for a printer to test in real, but you can try the following modification:
Modified for printer:
Sub txtInput_Action
    Dim strTx As String
    strTx = $"${Chr(27)}@"$                                            '--- First reset printer
    strTx = strTx & "SIZE 39.0 mm,18.0 mm" & CRLF
    strTx = $"${strTx}DIRECTION 0${CRLF}"$                            ' --- Try 0 or 1
'    strTx= strTx & "DIRECTION 1,0" & CRLF
    strTx= strTx &"GAP 2 mm,2 mm" & CRLF                           ' --- Stay away from the paper edge
'    strTx= strTx &"GAP 0 mm,0 mm" & CRLF
    strTx= strTx &"CODEPAGE 850" & CRLF
    strTx= strTx &"CLS" & CRLF
    strTx = $"${strTx}QRCODE 37,13,H,4,N,0,"QRCODE1"${CRLF}"$
'    strTx= strTx &"QRCODE 37,13,0,H,4,A,0," & Chr(34) & "QRCODE1" & Chr(34) & CRLF
    strTx= strTx & "PRINT 1,1" & CRLF
    astream.Write(strTx.GetBytes("UTF8"))
End Sub
Same result - prints only the code:
Label.jpg
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
The used the printer as a text-only printer and then you get the print commands as output. You are missing the routines present in the XP-365b printer driver to convert these printer commands to the specific printer instructions. What happens if you run the commands via the XP-365b printer driver?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I had a quick look online for this issue, there is a suggestion that there is an option in the printer driver settings to turn on QRCode printing. I can't confirm this as I don't have the printer but may be worth checking.
 
Upvote 0
Top