# PDF in Java FX anzeigen



## MiMa (24. Okt 2016)

Hallo,
mache nun meine ersten Gehversuche mit Oberflächen unter JavaFX.
Es soll vieles einfacher, besser und schneller zu implementieren sein?
Derzeit habe ich in einem Fenster eine SplitPane, linke eine ListView und rechts eine WebView.
In der Listview<File> werden mir Dateien aus einem Verzeichnis aufgelistet. 
Nun möchte ich selektierte Datei im rechten Fenster der WebView anzeigen lassen.
Die Dateien sind PDF, TIF, PNG, JPEG, TXT, DOC, PPT.  
Im Netz gelesen, scheint das wohl mit PDF nicht ganz so einfach zu sein? Viele Infora sind auch einige Jahre her. Weiss jemand, wie man das am besten lösen kann?
Vielen Dank


----------



## Robat (24. Okt 2016)

Hey MiMa,

mMn. ist das mit reinem Java nicht möglich. Du könntest aber ein wenig JS mit einbinden.
Schau mal hier nach: http://enriquezrene.com/home/index.php/en/javafx-english/showing-pdf-files-on-javafx

Hoffe, dass ich dein Problem richtig erfasst habe.

Gruß
Robert


----------



## MiMa (24. Okt 2016)

Danke für den Link.
Den hatte ich auch gefunden, geladen, gemacht und hat ledier nicht geklappt. Woran es dann liegt, kann ich  nicht sagen. JavaScript kann ich nicht. Habe mich auch gefagt, wo die URL der Datei her kommen soll?

```
String url = getClass().getResource("web/viewer.html").toExternalForm();
```
Dort wird soweit ich das verstehe, der Viewer geladen. Der Viewer muss doch einenen Inhalt bekommen?
Erhhalte Fehler vom Construct Loader.


----------



## Robat (24. Okt 2016)

MiMa hat gesagt.:


> Danke für den Link.
> 
> ```
> String url = getClass().getResource("web/viewer.html").toExternalForm();
> ```





> PDF.js has a viewer.html file example to show a pdf file that you can find in the same directory, and we are going to use it. Of course, you can use any one.



So wie ich das verstehe, ist das nur ein Sample pdf file auf html Ebene.
Hast du mal versucht das so abzuwandeln:

```
String url  = getClass().getResource(<LINK AUS DEINEM TREE VIEW>);
```


----------



## MiMa (24. Okt 2016)

Hat auch nichtfunktioniert. Daher hatte ich nach einer weiteren lösung gesucht.


----------



## dzim (24. Okt 2016)

Hast du schon mal das hier probiert?
https://github.com/IDRSolutions/maven-OpenViewerFX-src
Das ist der OpenSource-Teil eines PDF-Viewers für FX. Dahinter steht eine Firma, die auch eine kommerzielle (und sicher um ein vielfach mächtigere) Variante anbietet.

Ansonsten zur JavaScript-Idee: Ich vermute, du müsstest den Link im HTML dynamisch erstellen. Also dein anzuzeigendes HTML laden, in dem indealerweise *alle* Resourcen entweder eingebettet sind, oder ab die Links erst einmal per Platzhalter erstellen und dann auf die selbe Art wie du die HTML lädst - also *getClass().getResource("/absolute/path/to/resource.[html|js|pdf|...]").toExternalForm() *(absolut nur, um sicherzustellen, das du "richtig" bist)*. Warum auf diese Art?* Der WebView läuft im Java-Context, also musst du auf die Resourcen, die du dort im WebView verwenden willst, auf die selbe Art angeben.
Probier es mal aus und berichte mal. Oder baue ein kleines selbstlaufendes Beispiel, mit dem wir experimentieren könnten (ich hätte jetzt keine Lust alle Dependencies - JavaScript, zum Beipiel - zu erraten).

Grüsse


----------



## MiMa (24. Okt 2016)

Selbst mit den Quellcodes aus dem GIT habe ich es nixcht ans laufen bekommen.
Ist eines von vielen Beispielen im Netz, die nicht funktionieren. 

Allerdings habe ich hier einen Quellcode, der direkt nach dem Hinzufügen der Bibliothek direkt funktionierte. 
https://kbdeveloper.qoppa.com/?p=2973

OpenViewerFX habe ich noch nicht probiert, werde es aber nachholen.


----------



## MiMa (24. Okt 2016)

Ich habe den Quellcode mal bis auf das nötigste gekürzt um zu sehen, was nötig ist.

```
public class JavaFXNotes extends Application {

    // Variablendefinition
    private ObjectProperty<File> pdf = new SimpleObjectProperty<>();

    @Override
    public void start(Stage primaryStage) throws Exception {

        pdf.set(new File("K:\\01 Quelle\\2015-01-01_Rechnung.pdf"));

        Parent root = FXMLLoader.load(getClass().getResource("Notes.fxml"));
        Scene primaryScene = new Scene(root);
        Stage embeddedStage = new Stage();
       
        SwingNode sw = new SwingNode();
        sw.setContent(createAndLoad());
        Scene embeddedScene = new Scene(new StackPane(sw), 800, 1200);
        embeddedStage.setScene(embeddedScene);
        embeddedStage.show();
    } // start

    public PDFNotesBean createAndLoad() {
        PDFNotesBean notesBean = new PDFNotesBean();
        new Thread(() -> {
            try {
                notesBean.loadPDF(new FileInputStream(pdf.get()));
            } catch (PDFException | FileNotFoundException e) {
                throw new RuntimeException(e);
            }
        }).run();
        return notesBean;
    } // createAndLoad
} // JavaFXNotes
```
Allerdings werden zwei Scenen erstellt. Benötigt wird aber doch nur eine?
Wäre super, wenn noch jemand den Code kürzen könnte.
Einserseits benötige ich die Scene mit root damit es einen Startpunkt gibt, und derzeit weis ich nicht wie ich die embeddedScene umbauen mus, damit es noch funktioniert.

Danke


----------



## dzim (25. Okt 2016)

Zugegeben, OpenViewerFX ist etwas... frickelig. Immerhin ist es einfach einen kompletten PDF-Viewer damit einzubinden. In 5min war das getan. Es man jetzt im Code studieren müsste, wäre, wie man nur die reine PDF und die Steuerkomponenten bekommt. Denn ich möchte nicht den Viewer mitsamt Menü und damit einhergehend nur der Option, über dieses PDFs öffenen zu können.


----------



## MiMa (27. Okt 2016)

Ja das stimmt. Nur das nötigste.
Derzeit versuche ich heraus zu finden, wie ich die selektierten File Dateien anzeigen kann.
Hat da jemand ein gutet Tut gesehen?
Danke


----------



## MiMa (28. Okt 2016)

Soweit funktioniert es jetzt.
Dateien werden aufgelistet, eine selektiert, wird diese rechts neben der Liste im Anzeigebereich angezeigt.
Allerdings ist der Viever völlig überladen. Mache mich jetzt auf die suche nach einem neuen PDF Renderer.


----------



## MiMa (28. Okt 2016)

Habe mir mal das Netbeansprojekt geladen aber scheint nicht zu funktionieren. Habe selbst versucht es mit pdfbox zum laufen zu bekommen. Leider ohne Erfolg.
Würde einer von Euch mal probieren!
https://github.com/torutk/pdfviewer


----------



## dzim (15. Nov 2016)

Ich glaube, das Beispiel basiert auch auf dem PDF-Renderer von swinglabs. Ich habe mit JavaFX gestern ein laufendes Beispiel erstellt, nachdem ich das Repo hier angeschaut habe
https://github.com/james-d/PdfViewer
Der Autor (James_D) ist ein relativ aktiver JavaFX-"Berater" auf StackOverflow. Das Repo ist älter (JavaFX2) und der Code ist noch Pre-Java8 (keine Lambdas). Da es kein Maven-Projekt ist, musst du dir die dependencies selbst suchen, aber eigentlich ist es leicht zu finden.
Ich hatte es nach dem Beispiel in ca. 15min fertig.

Grüsse,
Daniel


----------



## MiMa (16. Nov 2016)

Nachdem ich mich mehr mit pdfbox beschäftigt habe, und mir aufmerkasam die Fehlermedlungen angeschsut habe, bin ich auf die Idee gekommen eine nältere Version von PDFbox zu benutzen. Da ich im Netz keine Version 2.0.1 mehr finden konnte, habe ich in meinem Backups eine Version 2.0.0-RC3 gefunden. Damit hat es dann geklappt.


----------



## MiMa (16. Nov 2016)

Ich tu mich da noch ein bischen schwer die Beispiele der neuesten 2.0.3 zu finden. Die neueste Version arbeitet ganz anders als die vorherige. Auf der Apache Seite steht, das diese in einem SVN liegen. Ich habe überhaupt keine Ahnung davon. Weis da jemand einen Rat?
Danke


----------



## MiMa (30. Jan 2018)

Die Aufgabenstellung ist jetzt schon eine ganze weile her, aber das Problem besteht immer noch.
Habe es eine ganze Zeit lang verdrängt da ich nicht weiter weiss.
Wie gesagt im Netz kursiert so viel umher, aber leider funktioniert nichts wirklich.
Mal funktioniert der Code nicht, mal gibt es keine jar Datei mehr, alles ziemlich unbefriedigend.
Auf dem Mac geht das alles durch das PDF-Kit wesentlich einfacher.
Ich würde mich freuen, wenn mir jemand helfen könnte das Problem zu lösen.
Aufgabe:
Ich habe eine GUI als FXML mit Scene Builder erstellt. Dort soll in einem Bereich eine PDF angezeigt werden.
Vielen Dank 
Mi


----------



## dzim (5. Feb 2018)

Hm... Schade, dass du dich nicht einfach etwas selbst daran probiert hast. Der Code ist da, er muss nur optimiert/angepasst werden! Wie gesagt, waren die Dependencies nicht schwer zu finden, wenn man weiss, wonach man suchen musst. Und die Tipps hatte ich dir gegeben.

Meine Proof-of-Concept-Variante (sicher auch nicht fehlerfrei!), die sich in leicht abgewandelter Form auch in einem von mir mitentwickelten Produkt im produktiven Einsatz befinden, kann man hier finden:
https://github.com/bgmf/poc/blob/ma...ava/eu/dzim/shared/fx/ui/CustomPdfViewer.java
Hat ein paar Abhängigkeiten, die man vielleicht so nicht braucht, für mich war es jedoch sinnvoll.
Ich hoffe, damit schliesst sich dieses Thema nun endlich.

Hinweis: Am Ende ist es nichts weiter, als mittels swinglabs und SwingFXUtils aus dem PDF JavaFX-Images zu generieren und diese dann irgendwie einzubetten. Bei mir in eine etwas überbordende Lösung mit einem "SwipePane" (Simples StackPane, bei dem die Kinder horizontal oder Vertikal ausgelegt und translated werden) und "SimpleDialog" (leichtgewichtiger Dialog ohne eigenes Fenster, dafür in StackPane-Overlay).


----------



## MiMa (5. Feb 2018)

Vielen Dank für Deine Antwort.
Aber ja, ich habe mehr als 14 Tage an dem Problem gesessen. Im Netz gesucht, selbst probiert, Code Studiert Bücher gelesen und versucht das wissen für meine eigene Anwendung um zu setzen.
Ich habe auch schon das eine oder andere PDF anzeigen können, mit völlig Überladenen Frameworks. Also konnte ich es nicht so umsetzen wie ich es gern hätte. Auf dem Mac war das so einfach und kann nicht verstehen das man sich in Java sowas von abmühen muss. Die Bibliotheken sind meiner Meinung echter Krampf und das ganze ist für mich echt mühselig. Daraufhin habe ich das ganze dann mal hinten an gestellt und mich mehr mit JavaFX beschäftigt um meine Codezeilen auch mal eine GUI ein zu binden.
Das PDF Problen wird stätesdens nächste Woche wieder auf mich zukommen.


----------



## dzim (7. Feb 2018)

MiMa hat gesagt.:


> Auf dem Mac war das so einfach




Nun ja, wenn es Bibliotheken für das UI-Framework gibt, ist das klar. Jedoch fällt es mir auch jetzt nicht schwer, andere Bibliotheken für JavaFX zu finden. Ob die dann deinem Geschmack entsprechen...
Auch jetzt wieder: Suche ich nach "javafx pdf viewer" komme ich auf ein paar brauchbare Lösungen. Am interessantesten ist IHMO noch diese hier https://blog.samirhadzic.com/2017/02/09/show-pdf-in-your-application/ (über den WebView von JavaFX).
Meine Variante ist ok, hat aber aufgrund der Swing-Dependencies ihre Schwächen. Und neue PDF-Features (gibt es so was überhaupt) werden wohl kaum mehr von der verwendeten Swing-basierten Bibliothek abgedeckt.

Nimm's bitte nicht zu persönlich, aber ich glaube, du hast einfach grundsätzlich noch zu viele offene Baustellen, was das Programmieren mit Java angeht, dadurch fällt es dir schwer den Wald vor Bäumen zu sehen.

BTW: IMHO ist auf dem Mac nichts wirklich besser als auf anderen Plattformen/Betriebssystemen...


----------



## MiMa (7. Feb 2018)

dzim hat gesagt.:


> Nimm's bitte nicht zu persönlich, aber ich glaube, du hast einfach grundsätzlich noch zu viele offene Baustellen, was das Programmieren mit Java angeht, dadurch fällt es dir schwer den Wald vor Bäumen zu sehen.


Du hast recht, bisher habe ich Java Programme immer ohne GUI erstellt. Einfach Variablen statt Eingabefenster verwendet. Seit kurzem erst beschäftige ich mich intensiv mit JavaFX und gebe auch zu das ich darin noch am anfang stehe, gebe mir aber richtig mühe und investiere am Tag viel Zeit.
PDF und Java habe ich vorab getestet weil ich meine Mac Applikation mal mit Java erstellen wollte. Dank des PDF Kits in macOS ging das tasächlich viel einfacher, aber wenn es eine anständige Bibliothek für Java gibt, würde das mit sicherheit genaus einfach gehen.
Eigentlich habe ich keine großen Ansprüche was dem PDF viewer angeht. 
Ich wollte nur nichts überladenes in einem eigenen Fenster darstellen und auf Swing verzichten.


----------



## dzim (12. Feb 2018)

MiMa hat gesagt.:


> Ich wollte nur nichts überladenes


Das ist einfach...


MiMa hat gesagt.:


> und auf Swing verzichten


... das wird schon schwieriger.

Es gibt einfach kaum (Open Source) Projekte, die das Rendern von PDFs machen. Daher liegt hier das Problem. Die meisten verwenden Java(FX) wahrscheinlich primär für general purpose UIs und für so Formular-Gedöns. Spezielle Sachen werden häufig nativ, oder mit Sprachen und deren Frameworks gemacht, die das eben mitbringen.

Java ist halt eine Eierlegende Wollmilchsau, mit der man vielen machen kann, aber das heisst nicht, dass es a) immer einfach oder b) gut (oder wenn überhaupt) unterstüzt wird. Die meisten verwenden es halt für Server-Zeug, daher findest du auf dem Gebiet auch die meisten Frameworks.


----------



## MiMa (12. Feb 2018)

Danke für Deine Antwort.
Ich habe schon eine gefühlte Ewigkeit damit verbracht nach Bibliotheken und Lösungen zu suchen. Oft finde ich immer die gleichen Bibliotheken und Lösungsansätze. Mehrfach war ich der Versuchung nahe, mein Mac Programm weiter aus zu bauen. Mein Ziel ist es aber diesmal ein Platformunabhängiges Programm zu erstellen und versuche eisern zu bleiben. Im Laufe der Zeit sammle ich immer mehr Erfahrungen mit Java, was Objective-C ziemlich nahe kommt. JavaFX ist neu für mich und versuche ausschließlich mit der neuen Technologie neue Projekte zu realisieren. Es gibt aber auch JavaScript Lösungen, aber ich kann kein JavaScript und deshalb habe mich nicht länger damit beschäftigt.


----------

