B4J Tutorial B4J PDFBox test project

pdfbox_test_000.PNG

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:
library reference:
#AdditionalJar: pdfbox-app-2.0.26.jar
When the application starts the first thing you have to do is open the file dialog by clicking on the blue button on the top left.
pdfbox_test_001.PNG

pdfbox_test_002.PNG

Then the selected file will be loaded. In the image below the B4X booklet B4X Basic Language is loaded.
pdfbox_test_003.PNG

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.
pdfbox_test_004.PNG

On my old laptop the 139 pages from the booklet were loaded in approximately 17 seconds.
pdfbox_test_005.PNG

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.
pdfbox_test_006.PNG

Click on the Scrolling switch again and you can use the paging mode again. The now green buttons can be used.
pdfbox_test_007.PNG

The essential code from the application looks like this:
essential code:
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
You can download the attached zip-file to do some testing.
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.
Happy testing!
Paul
 

Attachments

  • pdfbox_test.zip
    5.3 KB · Views: 356

PaulMeuris

Active Member
Licensed User
If the window is resized to a different width then the zoom factor can be adjusted to show the page to the full width of the window.
These are the changes that can accomplish this:
adjustments for the zoom factor:
' in Class_Globals
    Private devwidth As Int
' in B4XPage_Created before the pdffile initialization
    devwidth = B4XPages.GetNativeParent(B4XPages.MainPage).RootPane.Width
' add the resize subroutine
Private Sub B4XPage_Resize (Width As Int, Height As Int)
    devwidth = B4XPages.GetNativeParent(B4XPages.MainPage).RootPane.Width
End Sub
' the first line in renderpage
    zoom = devwidth / 850
' in the subroutine renderallpages below the pnpdf.RemoveallNodes
    zoom = devwidth / 850
The best thing you can do is to resize the window before you load (open) a PDF document.
The width of the document will then automatically be adjusted because the zoom factor changed.
When you have already loaded a PDF file and you resize the window then the effect will be shown in the paging mode by changing a page.
If you switch to scrolling the effect can only be shown by reloading (opening) the PDF file.
The scrolling pane has for each page an image of a different width then the width of the window.
Flipping the switch 2 times does not reload the PDF file because it is already loaded.
 
Top