In my search for a good PDF file viewer in B4J i came across a few examples.
DonManfred wrote a PDFBox (2.0.17) wrapper. Spsp wrote a ‘clsPDFViewer’.
The thread from knutf: pdfboxwrapper looked the most promising. So most of the credit goes to knutf for this application.
I took the essential java object statements and included them in my application.
I am using the Apache PDFBox 2.0.26 API and added the .jar reference in the Main module:
Then the selected file will be loaded. In the image below the B4X booklet B4X Basic Language is loaded.
The application provides two ways of viewing: page by page or scrolling.
In the paging mode the green buttons can be used to go to a specific page or the Page number input field can be used to type a page number and press on the ENTER key.
When you click on the Scrolling switch the full PDF document is added to the scrolling pane.
On my old laptop the 139 pages from the booklet were loaded in approximately 17 seconds.
In this mode the red buttons can’t be used. You can however scroll through the entire text.
The Page number input field can also be used to go to a specific page in the PDF document.
Click on the Scrolling switch again and you can use the paging mode again. The now green buttons can be used.
The essential code from the application looks like this:
Private Sub initpage joswing.InitializeStatic("javafx.embed.swing.SwingFXUtils") jofile.InitializeNewInstance("java.io.File",Array(pdffile)) joPDDocument.InitializeStatic("org.apache.pdfbox.pdmodel.PDDocument") jopdfdoc = joPDDocument.RunMethod("load",Array(jofile)) jorenderer.InitializeNewInstance("org.apache.pdfbox.rendering.PDFRenderer",Array(jopdfdoc)) dpi = joscreen.InitializeStatic("javafx.stage.Screen").RunMethodJO("getPrimary",Null).RunMethod("getDpi",Null) numpages = jopdfdoc.RunMethod("getNumberOfPages",Array()) lblnumpages.Text = " Total pages: " & numpages pagenumber = 1 zoom = 0.8 ivpdf.Initialize("") pnpdf.Initialize("") pnpagepdf.Initialize("") ftfpagenum.Text = pagenumber End Sub Private Sub renderpage(pnum As Int) img = jorenderer.RunMethod("renderImageWithDPI",Array(pnum-1,dpi*zoom)) ivpdf.SetImage(joswing.RunMethodjo("toFXImage",Array(img,Null))) pnpagepdf.RemoveAllNodes pnpagepdf.AddNode(ivpdf,0,0,ivpdf.Width,ivpdf.Height) sppagepdf.InnerNode = pnpagepdf sppagepdf.InnerNode.PrefHeight = 1185dip * zoom sppagepdf.VPosition = 0 End Sub Private Sub renderallpages If allpages_available = True Then Return End If pnpdf.RemoveAllNodes Dim toppos As Int = 0 For i = 0 To numpages - 1 img = jorenderer.RunMethod("renderImageWithDPI",Array(i,dpi*zoom)) Dim iv As ImageView iv.Initialize("") iv.SetImage(joswing.RunMethodjo("toFXImage",Array(img,Null))) pnpdf.AddNode(iv,0,toppos,iv.Width,iv.Height) toppos = toppos + (1185dip * zoom) Next sppdf.InnerNode = pnpdf sppdf.InnerNode.PrefHeight = 1185dip * zoom * numpages sppdf.VPosition = 0 allpages_available = True Sleep(0) End Sub
The application has some limitations.
I have set the dimensions fixed for a half-screen layout (on my 15.6 inch old laptop). This way i can look something up and compare it with the source code in the IDE on the other half of my screen.
The zoom factor is set to 0.8 which gives a good scrolling response. A zoom factor of 1 seems to be causing some slow scrolling.
The page layout is ideal for A4 pages in portrait mode. In landscape mode you have to resize the window.