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: 642
  • Printer.zip
    14.2 KB · Views: 354
Last edited:

DonManfred

Expert
Licensed User
Longtime User

skeedsr

Member
Hy and thank you for this library.

i would like to ask you if i can print some part of my form..

example, if i try to stamp a list view, work well

lvoreasso as listview

PJ.PrintPage2(pl,lvoreasso)

but i would like to print two or three listview or some part of my form..

i try..
PJ.PrintPage2(pl,lvoreasso&lvcommesse) but not work..

yhanks!

Livio
 

Tayfur

Well-Known Member
Licensed User
Longtime User
I use the underlying code to print the item (PANE1) on the form.
The position of PANE1 in the form is Left: 140 Top: 100.
I send you the results from the printer in attachment.
I wanted PANE1 to be in the L: 0 / T: 0 position on A4 page. But it printed it in the same position (L: 140 / T: 100) as like in mainforms.

How is fix it witt setting of printer lib.

B4X:
Sub Button1_MouseClicked (EventData As MouseEvent)
'    Dim P As Printer = Printer_Static.GetDefaultPrinter
'    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob2(P)
'    PJ.PrintPage(Pane1)
'    PJ.EndJob
    Log("X:"&Pane1.Left&" Y:"&Pane1.top)
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob
    PJ.ShowPageSetupDialog(Null)
    PJ.ShowPrintDialog(Null)
  
    PJ.PrintPage(Pane1)
    PJ.EndJob
  
End Sub
Untitled.png
 

Attachments

  • JavaFX Print Job.pdf
    9 KB · Views: 628

stevel05

Expert
Licensed User
Longtime User
Can you upload the project?
 

stevel05

Expert
Licensed User
Longtime User
As it's printing the pane, it is positioned according to the layout of that pane. You will need to temporarily set the top and left to 0, then print it, you can hide it under a progress screen so the user doesn't see it move. Or duplicate the pane in another window off the screen.
 

Tayfur

Well-Known Member
Licensed User
Longtime User
As it's printing the pane, it is positioned according to the layout of that pane. You will need to temporarily set the top and left to 0, then print it, you can hide it under a progress screen so the user doesn't see it move. Or duplicate the pane in another window off the screen.

:(
thanks for help;
I must a create new form and add in pane (layout must be set 0;0).

is it correct?
 

stevel05

Expert
Licensed User
Longtime User
Yes, or temporarily move it in the existing pane.
 

stevel05

Expert
Licensed User
Longtime User
This won't print an excel document. Just the image of it that is displayed in a Node.
 

jcohedman

Member
Licensed User
Longtime User
I'm using this to print in a Epson LX-300+, and it functions!

but... the question is: how to change the font size?
can anybody help me?

thanks...
 

stevel05

Expert
Licensed User
Longtime User
It should print the fonts relative to the content of the displayed node. I say relative because it would be a different size for example if you use the scale sub, or select the expand/reduce page size in the print driver.

So you need to change the font on the Label or Textarea/field (s) that are contained in the node you are printing.
 

AHilton

Active Member
Licensed User
Longtime User
Has anyone managed to get this to work with a label printer? I am trying to get a simple, short label node to print on a Brother QL-720NW printer and it's giving me an error "java.lang.illegalArgumentException: Bad margins" or "Illegal Parameters" regardless of what I try.
 

Swissmade

Well-Known Member
Licensed User
Longtime User
Has anyone managed to get this to work with a label printer?
Yes I have
This error is from the printer. You have to create a paper for your label size and select this. Margin very is important
 

AHilton

Active Member
Licensed User
Longtime User
Do you see anything glaringly wrong here ...

B4X:
    Dim PR As Printer = Printer_Static.GetDefaultPrinter
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob2(PR)
    For Each SP As JavaObject In pr.GetPrinterAttributes.GetSupportedPapers
        Dim PA As Paper
        PA.SetObject(SP)
        If PA.GetName.Contains("1.1") And PA.GetName.Contains("3.5") Then
            Dim r As Reflector
            R.Target = SP
            R.SetField2("height", 90)
            R.SetField2("width", 29)
            PA.SetObject(SP)
            Exit
        End If
    Next
    Dim PL As PageLayout = pr.CreatePageLayout2(PA, PageOrientation_Static.LANDSCAPE, "HARDWARE_MINIMUM")
    PJ.PrintPage2(PL, Label)
    PJ.EndJob
 

Swissmade

Well-Known Member
Licensed User
Longtime User
Do you see anything glaringly wrong here ...

B4X:
    Dim PR As Printer = Printer_Static.GetDefaultPrinter
    Dim PJ As PrinterJob = PrinterJob_Static.CreatePrinterJob2(PR)
    For Each SP As JavaObject In pr.GetPrinterAttributes.GetSupportedPapers
        Dim PA As Paper
        PA.SetObject(SP)
        If PA.GetName.Contains("1.1") And PA.GetName.Contains("3.5") Then
            Dim r As Reflector
            R.Target = SP
            R.SetField2("height", 90)
            R.SetField2("width", 29)
            PA.SetObject(SP)
            Exit
        End If
    Next
    Dim PL As PageLayout = pr.CreatePageLayout2(PA, PageOrientation_Static.LANDSCAPE, "HARDWARE_MINIMUM")
    PJ.PrintPage2(PL, Label)
    PJ.EndJob
This was also my mistake
You have to set a page in your Printer and select this page.
What you are doing is, you create a page but you don't tell this your printer.
Add a new page to your Printer
 

AHilton

Active Member
Licensed User
Longtime User
This was also my mistake
You have to set a page in your Printer and select this page.
What you are doing is, you create a page but you don't tell this your printer.
Add a new page to your Printer


And what is the command to tell my printer that?
 

Swissmade

Well-Known Member
Licensed User
Longtime User
And what is the command to tell my printer that?
I have create this in Windows.
Just add the page to the Printer.
I don't know your printer how this has to be done.
This is the code I print Labels with QRCode
The Printer and Paper size from the Printer I have in a list.
B4X:
Private Sub PrintBarcode()
Try
    JobPrint = False
    Dim img As Image
    img.Initialize(File.DirAssets, "LogoEntrada.png")
    imgBrand.SetImage(img)
    lblText.Text = Main.txtBarCodeText ' "Some Text"

    img.Initialize(Main.DirApp, "Barcodebuild.png")
    imgBarcode.SetImage(img)
   
    lblBarcodeText.Text = txtTextForBarcode.Text
    PrintForm.Show
    Dim PPX As Paper
    PPX.Initialize()
    Dim PC As Printer
    PC.Initialize()
    Dim PL As PageLayout
    PL.Initialize()
'Get the Papersize   
    Dim Width As Double
    Dim Height As Double
    Dim PP As JavaObject
    Dim r As Reflector
Dim SetPageFormat As Boolean = True 'False
'Get the Printer from List
PC = PrinterList.Get(lstPrinters.SelectedIndex)

PP = PrintersPaperSizeList.Get(lstPrintersPaperSize.SelectedIndex)
r.Target = PP
Width = r.GetField("width")
Height = r.GetField("height")

If SetPageFormat = True Then
    PPX.SetObject(PP)
    PL = PC.CreatePageLayout(PPX, PageOrientation_Static.PORTRAIT,1, 1, 1, 1)
End If
    PJ = PrinterJob_Static.CreatePrinterJob2(PC)


    If HavePrinter.IsInitialized = False Then
        HavePrinter.Initialize()
    End If    
'    'Print without dialogs

If SetPageFormat = True Then
    PJ.PrintPage2(PL, PrintForm.RootPane)
Else
    PJ.PrintPage(PrintForm.RootPane)
End If
    PJ.EndJob
    PrintForm.Close
    JobPrint = True
Catch
    Functions.ShowLog("Error PrintForm modBarcode", True, False, LastException.Message)
End Try
End Sub
 

AHilton

Active Member
Licensed User
Longtime User
Which label printer are you using, swissmade?

This simply will not work with the Brother QL-xxx label printers. I've tried everything getting JavaFX8 to print to them and can't waste anymore time.
 
Top