Repository navigation
Replies: 1 comment
|
HI @A47248, the core reason PDF.js fails or freezes inside JavaFX’s WebView is that JavaFX WebView uses an older, embedded WebKit engine that lacks full support for modern JavaScript features and web standards used by standard PDF.js builds—specifically modern ECMAScript features (such as import.meta, Top-Level Await, Private Class Fields, or globalThis) and modern Canvas/Worker APIs. When engine.load() runs, modern JS features trigger silent syntax/runtime errors in JavaFX WebKit, preventing the viewer script from initializing properly. Solution 1: Use the Legacy/ES5 Build of PDF.js Download or host the legacy pre-built library from npm (pdfjs-dist/legacy/build/pdf.js) or a CDN like cdnjs/unpkg. Ensure you configure pdfjsLib.GlobalWorkerOptions.workerSrc to point to pdf.worker.js (legacy build as well). Rather than using the complex default UI viewer (viewer.html), render PDF pages directly using a minimal custom HTML file to avoid unsupported UI component scripts. Minimal HTML Page (pdf_viewer.html): <!DOCTYPE html>
<html>
<head>
<!-- Use legacy ES5-compatible build -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.js"></script>
<style>
body { margin: 0; background-color: #525659; overflow: auto; }
canvas { display: block; margin: 10px auto; box-shadow: 0 0 10px rgba(0,0,0,0.5); }
</style>
</head>
<body>
<div id="pdf-container"></div>
<script>
// Set worker path to legacy worker
pdfjsLib.GlobalWorkerOptions.workerSrc =
'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.js';
function loadPdf(url) {
pdfjsLib.getDocument(url).promise.then(function(pdf) {
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
pdf.getPage(pageNum).then(renderPage);
}
}).catch(function(err) {
console.error('PDF.js Error: ' + err.message);
});
}
function renderPage(page) {
var viewport = page.getViewport({ scale: 1.2 });
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
document.getElementById('pdf-container').appendChild(canvas);
page.render({
canvasContext: context,
viewport: viewport
});
}
</script>
</body>
</html>Solution 2: Debug JavaFX WebEngine JS Errors import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
public class PdfViewApp extends Application {
@Override
public void start(Stage stage) {
WebView webView = new WebView();
WebEngine engine = webView.getEngine();
// Enable JavaScript console logging
engine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
if (newState == javafx.concurrent.Worker.State.SUCCEEDED) {
JSObject window = (JSObject) engine.executeScript("window");
window.setMember("javaConsole", new JavaConsole());
engine.executeScript("console.log = function(message) { javaConsole.log(message); };");
engine.executeScript("console.error = function(message) { javaConsole.error(message); };");
}
});
// Load your local or legacy hosted PDF viewer HTML
engine.load("http://localhost:8080/pdf_viewer.html");
stage.setScene(new Scene(webView, 1024, 768));
stage.show();
}
public static class JavaConsole {
public void log(String message) {
System.out.println("[JS LOG] " + message);
}
public void error(String message) {
System.err.println("[JS ERROR] " + message);
}
}
}Summary Checklist for JavaFX WebView Disable Web Workers (Optional Fallback): If Web Workers fail to instantiate inside JavaFX WebKit, force PDF.js to run synchronously in the main thread: JavaScript |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I'm using JavaFX (21) webview and want to embed PDF.js in my application to view pdf files.
I did setup a http server to host the files that I want to access. After setting up all properly and verify that all work on the browser, I tried it on the webview.
After some debugging I realise that the problem isn't with my code. A simple example shows that its not working properly.
This looks like the javascript didn't load properly, because didn't show the pdf or have any type of interactability on the drop down menus.
If someone knows how to make it work properly on the JavaFX WebView, please explain what I'm doing wrong.
All reactions