B4J Library B4j Print JavaFX8

Here is a B4j library written in B4j to access the full Printer modules provided with JavaFX8. Full source code is available.

At it's simplest, you can print a node using:
B4X:
    Dim P As Printer = Printer_Static.GetDefaultPrinter
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob2(P)
    PJ.PrintPage(lblTest)
    PJ.EndJob

Or with dialogs:

B4X:
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob
    PJ.ShowPageSetupDialog(Null)
    PJ.ShowPrintDialog(Null)
    PJ.PrintPage(MainForm.RootPane)
    PJ.EndJob

Code to scale a view to print on a single page.
Scale output:
Sub ScaleOutput(P As Printer,N As Node) As Node
    Dim PL As PageLayout = P.GetDefaultPageLayout
    Dim ScaleX,ScaleY As Double
    Dim NJO As JavaObject = N
    Dim JO As JavaObject = N
    ScaleX = PL.GetPrintableWidth / JO.RunMethodJO("getBoundsInParent",Null).RunMethod("getWidth",Null)
    ScaleY = PL.GetPrintableHeight / JO.RunMethodJO("getBoundsInParent",Null).RunMethod("getHeight",Null)
    Dim SJO As JavaObject
    SJO.InitializeNewInstance("javafx.scene.transform.Scale",Array(ScaleX,ScaleY))
    NJO.RunMethodJO("getTransforms",Null).RunMethod("add",Array(SJO))
    Return NJO
End Sub

Usage:
    'Print with dialogs
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob
    If PJ.ShowPageSetupDialog(Null) Then
        If PJ.ShowPrintDialog(Null) Then
'            PJ.PrintPage(MainForm.RootPane)
            PJ.PrintPage(ScaleOutput(PJ.GetPrinter,MainForm.RootPane))
            PJ.EndJob
        Else
            PJ.CancelJob
        End If
    Else
        PJ.CancelJob
    End If

Reset node size after scaling:
'where N would be MainForm.Rootpane in the above example
N.As(JavaObject).Runmethod("getTransforms",Null).as(List).Clear

Depends on: JavaFX8, JavaObject

Documentation (apart from that in the library) is available here: http://docs.oracle.com/javase/8/javafx/api/index.html?javafx/print/Printer.html
Click on javafx.print in the All Classes Packages frame to see all the relevant classes.

I've ignored Enums where strings are acceptable for simplicity's sake.

V0.6 fix improperly formed XMLmessage displayed in IDE help (post #6)
V0.7 added #RaisesSynchronousEvents to PrinterJob module as described here : https://www.b4x.com/android/forum/t...ble-getting-jfx8print-dialogs-to-work.133964/
V 0.8 Released as a B4xLib Enums now return string values instead of ENum objects.

Full code is in Printer.zip if you just want to look at the project without unzipping the B4xlib
Enjoy
 

Attachments

  • jFX8Print.b4xlib
    11.1 KB · Views: 676
  • Printer.zip
    14.2 KB · Views: 383
Last edited:

Swissmade

Well-Known Member
Licensed User
Longtime User
Which label printer are you using
The Printer used is a Citizen.
Put if your code is wrong this will also not work.
Try to set a pdf printer as default end test it with this printer.
 

AHilton

Active Member
Licensed User
Longtime User
It works just fine on several printers (dot matrix, laser, inkjet and virtual ones). Just not on these Brother label printers. I've moved on from B4J on this one and just made a C app to pass off any label printing. I gave it 4 hours ... can't give it any more time for something so basic.

And judging from the dearth of printing support from Java, I'm considering just bypassing B4J for ALL of my printing needs until it gets straightened out.
 

Swissmade

Well-Known Member
Licensed User
Longtime User
I hope you get it done.
 

stevel05

Expert
Licensed User
Longtime User
Just not on these Brother label printers.

Out of curiosity (I do not have a label printer to try it on). When you say it doesn't work, does if do anything? Form feed? Print garbage?
 

AHilton

Active Member
Licensed User
Longtime User
Stevel05: Read Post #54. When I did, finally, get it to not throw an error in B4J, the printer itself would throw an error of, basically, "the paper size doesn't match between what's in the printer and what the application is set to". Also tried ideas from https://stackoverflow.com/questions/11803741/printing-in-java-to-label-printer in addition to the one you posted. No good.

swissmade: That's points, not mm as per the stackoverflow examples. I tried all sorts of conversions from inches to mm to points. No good.

As I said, I moved on from B4J doing the printing now.
 

rboeck

Well-Known Member
Licensed User
Longtime User
@AHilton:
Hi, i tried now to print the first time to my old, professional label printer (Tec B482)
The steps i made:
Setup the label in your printer as standard printer and standard papersize - if you have a ff button, each press on the button should transport a label without an error.
I have used the original work from stevel05 -in the page setup dialog i can switch to the already defined label size ( i used 70 x 40 mm for testing), than i cleared all border settings to zero.
Now i ihad the print dialog, the printer was already choosen, but i had to manualy choose the paper size.
In the next dialog i set page count to three and i got three labels!

My printer driver has the possibility to define paper sizes, in the page setup dialog i have to choose the right one.
Because i dont have an brother printer, i cannot realy say, if my work is transferable to the brother printer.
Onr tipp for starting: First create you image or print size smaller then your label - if you get bigger, you get an error like yours, if you are smaller, most printer dont have a problem.
 

Swissmade

Well-Known Member
Licensed User
Longtime User
Thanks for sharing
 

afields

Member
Licensed User
helo. i've got a duplex printer but i cannot use it in duplex mode using that lib. how to tell it to printjob?
thanks to all
 

stevel05

Expert
Licensed User
Longtime User
Have you tried call the printdialog? Is the option there?
 

afields

Member
Licensed User
helo again and thanks for helping! i've got the printdialog as well as the paperdialog. the problem is that i need to give margins so it's not the default ( the defaults are correctly configured that in duplex mode). so i would need to indicate the duplex mode by code... i thought that using refletion but do not know what to indicate... thanks again!
 

stevel05

Expert
Licensed User
Longtime User
Once you get the print job object, you can set duplex using PJ.GetJobSettings.SetPrintSides("DUPLEX")
 

stevel05

Expert
Licensed User
Longtime User
You're welcome. This library is pretty much a full wrap of the available functions. There are so many options it can be difficult to find what you are looking for. If you need something else you can download the source (from the first post) and search for it, it's easier than going through the IDE intelli-sense looking for it.

Of course if you can't find it, just ask.
 

afields

Member
Licensed User
hello again... however it's not working in duplex..
so i'm sending two pieces of code:
the sub that would print in duplex:

B4X:
sub print_both
    Private P As Printer=GetPrinter("Zebra")
    Private papel As Paper
    Private papel2 As Paper
    Private pl As PageLayout
    
    pl.Initialize
    For Each PP As JavaObject In P.GetPrinterAttributes.GetSupportedPapers
        Dim PPP As Paper
        PPP.Initialize
        PPP.SetObject(PP)
        
    Next
    papel.Initialize
    papel2.Initialize
    papel=P.GetPrinterAttributes.GetDefaultPaper
    papel2=papel
    pl = P.CreatePageLayout(papel2, PageOrientation_Static.LANDSCAPE,0.5, 0.5, 0.5, 0.5)
    
    PJ = PrinterJob_Static.CreatePrinterJob2(P)
    PJ.GetJobSettings.SetPageLayout(pl)
    PJ.GetJobSettings.SetPrintSides("DUPLEX")
    For k=0 To 10000
                
    Next
    nodo=ScaleOutput(P,wv2)
    PJ.PrintPage(nodo)
End Sub

i'm using a node that is a webview. so in that node i have:

HTML:
<!DOCTYPE html>
<html>
    <head>
                <style>
                nome {
                    position: absolute;
                    left: 173px;
                    top: 30px;
                    font-family: Arial;
                    font-size: 80%;
                }
                anol {
                    position: absolute;
                    left: 333px;
                    top: 2px;
                    font-size: 90%;
                    color: white;
                }
                ano_tur {
                    position: absolute;
                    left: 350px;
                    top: 180px;
                    font-size: 90%;
                    color: white;   
                }
                n_proc {
                    position: absolute;
                    left: 327px;
                    top: 205px;
                    font-size: 80%;
                    color: white;   

                }
                n_carta {
                    position: absolute;
                    left: 327px;
                    top: 233px;
                    font-size: 80%;
                    color: white;   
                }
                foto {
                    position: absolute;
                    left: 328px;
                    top: 60px;
                }
                

                body {
                  
                    background-repeat: no-repeat;
                    background-size: 440px 270px;
                }
                #rectangle {
                    width: 10px;
                    height: 390px;
                    background: Red;
                }
                ini_re {
                    position: absolute;
                    left: -6px;
                    top: 10px;
                }
                
                #linha_cima {
                    background-color: #eee;
                }
                #tam_cel {
                   width=80px;
                }
                        
                #body2 {   
                    
                        transform: rotate(90deg);
                        position: absolute;
                        top: 200px;
                        left: 90px;
}
                }
                #centra {
                        align="right";
                }
                </style>
    </head>
                <body background="file:/C:/Users/aca/DOCUME~1/PROGS_~2/PARA_I~1/Objects/cartnv1819.jpg">
                <anol>2018/2019</anol>
                <nome>Afonso Almeida Louro</nome>
                <foto><img src="file:/C:/Fotos20072008/10826.JPG" width="90" height="110"></foto>
                <ano_tur>5ºA</ano_tur>
                <n_proc>Nº.Proc:11172</n_proc>
                <n_carta>Nº.Cart: 26058</n_carta>
                <p style="page-break-after: always;">&nbsp;</p>
                
    
                <div id="body2">
                        <ini_re><div id="rectangle"></div></ini_re>
                        <table width="238" border="1"   >
                           <tr id="linha_cima">
                            <th > </th>
                            <th style="font-size:70%;" >S</th>
                            <th style="font-size:70%;" >T</th>
                            <th style="font-size:70%;" >Q</th>
                            <th style="font-size:70%;" >Q</th>
                            <th style="font-size:70%;" >S</th>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center" height="36" >8:30-9:30</td><td align="center">EDT &nbspC07</td><td align="center">EMU &nbspC29</td><td align="center">POR &nbspB06</td><td align="center">EDV &nbspC10</td><td align="center">HGP &nbspB06</td>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center"  height="36" >9:40-10:40</td><td align="center">EDT &nbspC07</td><td align="center">EFI &nbspCAM</td><td align="center">POR &nbspB06</td><td align="center">MAT &nbspB06</td><td align="center">HGP &nbspB06</td>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center"  height="36" >10:55-11:55</td><td align="center">ING &nbsp   </td><td align="center">MAT &nbspB06</td><td align="center">CNT &nbspB06</td><td align="center">POR &nbspB06</td><td align="center">EDV &nbspC07</td>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center"  height="36" >12:05-13:05</td><td align="center">ING &nbsp   </td><td align="center">MAT &nbspB06</td><td align="center">CNT &nbspB06</td><td align="center">POR &nbspB06</td><td align="center">EDV &nbspC07</td>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center"  height="36">13:05-14:05</td><td align="center">MAT &nbspB06</td><td align="center">POR &nbspB06</td><td align="center">DA &nbspB06</td><td align="center">EFI &nbspCAM</td><td align="center">CNT &nbspB06</td>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center"  height="36" >14:10-15:10</td><td align="center">MAT &nbspB06</td><td align="center">POR &nbspB06</td><td align="center">ING &nbsp   </td><td align="center">EFI &nbspCAM</td><td align="center">MAT &nbspB06</td>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center"  height="36">15:15-16:15</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center"  height="36" >16:25-17:25</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td>
                          </tr>
                          <tr style="font-size:70%;">
                            <td align="center"   height="36">17:30-18:30</td><td align="center"bgcolor='#433E3C' >...</td><td align="center">HGP &nbspB06</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td><td align="center"bgcolor='#433E3C' >...</td>
                          </tr>

                        </table>
                </div>   
                </body>
                </html>

i have a page break <p style="page-break-after: always;">&nbsp;</p>
so why i do not have a duplex mode?
the printer is a zebra zxp series 7 with duplex mode...
thank you
 

stevel05

Expert
Licensed User
Longtime User
The print routine will only print what is displayed in the Webview, It won't get the instructions contained in the page.

I'm pretty sure it just does a screen capture and prints that. You would have to create each page and print it separately.
 

stevel05

Expert
Licensed User
Longtime User
@afields

It appears that there is a print method available on the WebEngine that drives the javafx webview that may help you. I came across it today when working on my own app.

To use it you need to pass a printer job object to the print method of the webengine, something like this:

B4X:
    WebView1.LoadUrl("http://b4x.com")
  
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob
    PJ.ShowPageSetupDialog(Null)
    PJ.ShowPrintDialog(Null)
    Dim WVJO As JavaObject = WebView1
    WVJO.RunMethodJO("getEngine",Null).RunMethod("print",Array(PJ.GetObject))
    PJ.EndJob

This will print the entire content of the webview, not just the visible portion unlike other views.

I'd be interested to know if it honors the page breaks.
 

afields

Member
Licensed User
first of all : thank you very much. it's with people like you that that big language will remain forever.
now the situation:
when i saw another post (https://www.b4x.com/android/forum/threads/printing-with-jfx8.79590) and also what you've said in:
You would have to create each page and print it separately
i came to the conclusion that:
to pirnt only the front side: print it and close the job
to print only the back side: print it and close the job
to print both side then: print data to front side, then print data to back side and finaly and just now close the printer job! ( what i was not doing) : ok know i've got front and back.
now my problem is to adjust the node to print well in the card)
of course that i'll test what you have wrote. and very soon cause i need it!
i'll inform you very soon
thanks!
 
Top