在JavaFX中开发桌面应用程序,它需要显示一个pdf。我读到在JavaFX(当前版本)中不支持pdf查看/显示,我也读过关于JPedal的文章。
现在,问题:
JPedal)如何将它嵌入到我的应用程序中。发布于 2013-08-13 21:19:19
JPedalFX示例代码和用法
使用JPedalFX的示例代码随JPedalFX下载一起提供。
就我而言,这有点蹩脚,但我将粘贴从JPedalFX库提供的示例查看器中复制的示例代码片段。代码依赖于包含在类路径上的jpedal_lgpl.jar文件(或应用程序jar清单中引用的库路径)。
如果您对JPedalFX的使用有进一步的疑问,我建议您使用直接联系IDR解决方案 (它们过去对我有响应)。
// get file path.
FileChooser fc = new FileChooser();
fc.setTitle("Open PDF file...");
fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("PDF Files", "*.pdf"));
File f = fc.showOpenDialog(stage.getOwner());
String filename = file.getAbsolutePath();
// open file.
PdfDecoder pdf = new PdfDecoder();
pdf.openPdfFile(filename);
showPage(1);
pdf.closePdfFile();
. . .
/**
* Update the GUI to show a specified page.
* @param page
*/
private void showPage(int page) {
//Check in range
if (page > pdf.getPageCount())
return;
if (page < 1)
return;
//Store
pageNumber = page;
//Show/hide buttons as neccessary
if (page == pdf.getPageCount())
next.setVisible(false);
else
next.setVisible(true);
if (page == 1)
back.setVisible(false);
else
back.setVisible(true);
//Calculate scale
int pW = pdf.getPdfPageData().getCropBoxWidth(page);
int pH = pdf.getPdfPageData().getCropBoxHeight(page);
Dimension s = Toolkit.getDefaultToolkit().getScreenSize();
s.width -= 100;
s.height -= 100;
double xScale = (double)s.width / pW;
double yScale = (double)s.height / pH;
double scale = xScale < yScale ? xScale : yScale;
//Work out target size
pW *= scale;
pH *= scale;
//Get image and set
Image i = getPageAsImage(page,pW,pH);
imageView.setImage(i);
//Set size of components
imageView.setFitWidth(pW);
imageView.setFitHeight(pH);
stage.setWidth(imageView.getFitWidth()+2);
stage.setHeight(imageView.getFitHeight()+2);
stage.centerOnScreen();
}
/**
* Wrapper for usual method since JFX has no BufferedImage support.
* @param page
* @param width
* @param height
* @return
*/
private Image getPageAsImage(int page, int width, int height) {
BufferedImage img;
try {
img = pdf.getPageAsImage(page);
//Use deprecated method since there's no real alternative
//(for JavaFX 2.2+ can use SwingFXUtils instead).
if (Image.impl_isExternalFormatSupported(BufferedImage.class))
return javafx.scene.image.Image.impl_fromExternalImage(img);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
/**
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.jpedal.org
* (C) Copyright 1997-2008, IDRsolutions and Contributors.
*
* This file is part of JPedal
*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---------------
* JPedalFX.java
* ---------------
*/SwingLabs PDF渲染器
此外,我使用了一个旧的基于SwingLabs Swing的pdf渲染器和JavaFX在过去用于为我的JavaFX网页浏览器渲染pdf。虽然在我开发浏览器时,Swing/JavaFX集成并不是JavaFX的一个受支持的特性,但它对我来说仍然很好。集成代码在PDFViewer.java和BrowserWindow.java中。
注意,Java2.2支持在Swing应用程序中嵌入JavaFX,Java8支持在JavaFX中嵌入Swing应用程序。
发布于 2017-02-04 12:26:46
好的,这是我的50美分。除了@ALabrosik和@ReneEnriquez答案。
下载pdf.js区并将其放在src/main/resources下
├── pom.xml
├── src
│ └── main
│ ├── java
│ │ └── me
│ │ └── example
│ │ ├── JSLogListener.java
│ │ ├── Launcher.java
│ │ └── WebController.java
│ └── resources
│ ├── build
│ │ ├── pdf.js
│ │ └── pdf.worker.js
│ ├── main.fxml
│ ├── web
│ │ ├── cmaps
│ │ ├── compatibility.js
│ │ ├── debugger.js
│ │ ├── images
│ │ ├── l10n.js
│ │ ├── locale
│ │ ├── viewer.css
│ │ ├── viewer.html
│ │ └── viewer.js创建以下fxml文件(您应该将WebView包装在TabPane或类似的容器中,以避免滚动支持方面的问题)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.web.WebView?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="576.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="me.example.WebController">
<center>
<TabPane>
<tabs>
<Tab text="PDF test">
<content>
<WebView fx:id="web" minHeight="-1.0" minWidth="-1.0" />
</content>
</Tab>
</tabs>
</TabPane>
</center>
<bottom>
<Button fx:id="btn" mnemonicParsing="false" text="Open another file" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>为了防止pdf.js在启动时打开演示pdf文件,打开web/viewer.js并清除DEFAULT_URL值。
var DEFAULT_URL = '';打开web/viewer.html并添加脚本块:
<head>
<!-- ... -->
<script src="viewer.js"></script>
<!-- CUSTOM BLOCK -->
<script>
var openFileFromBase64 = function(data) {
var arr = base64ToArrayBuffer(data);
console.log(arr);
PDFViewerApplication.open(arr);
}
function base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array( len );
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
</script>
<!-- end of CUSTOM BLOCK -->
</head>现在是控制器(请参阅代码注释以获得解释)。
public class WebController implements Initializable {
@FXML
private WebView web;
@FXML
private Button btn;
public void initialize(URL location, ResourceBundle resources) {
WebEngine engine = web.getEngine();
String url = getClass().getResource("/web/viewer.html").toExternalForm();
// connect CSS styles to customize pdf.js appearance
engine.setUserStyleSheetLocation(getClass().getResource("/web.css").toExternalForm());
engine.setJavaScriptEnabled(true);
engine.load(url);
engine.getLoadWorker()
.stateProperty()
.addListener((observable, oldValue, newValue) -> {
// to debug JS code by showing console.log() calls in IDE console
JSObject window = (JSObject) engine.executeScript("window");
window.setMember("java", new JSLogListener());
engine.executeScript("console.log = function(message){ java.log(message); };");
// this pdf file will be opened on application startup
if (newValue == Worker.State.SUCCEEDED) {
try {
// readFileToByteArray() comes from commons-io library
byte[] data = FileUtils.readFileToByteArray(new File("/path/to/file"));
String base64 = Base64.getEncoder().encodeToString(data);
// call JS function from Java code
engine.executeScript("openFileFromBase64('" + base64 + "')");
} catch (Exception e) {
e.printStackTrace();
}
}
});
// this file will be opened on button click
btn.setOnAction(actionEvent -> {
try {
byte[] data = FileUtils.readFileToByteArray(new File("/path/to/another/file"));
String base64 = Base64.getEncoder().encodeToString(data);
engine.executeScript("openFileFromBase64('" + base64 + "')");
} catch (Exception e) {
e.printStackTrace();
}
});
}
}一些pdf.js函数将无法工作:打开文件(因为pdf.js无法访问JAR外部的pdf.js)、打印等。要隐藏相应的工具栏按钮,可以向web.css添加以下行:
#toolbarViewerRight {
display:none;
}就这样。其余的代码都是琐碎的。
public class JSLogListener {
public void log(String text) {
System.out.println(text);
}
}
public class Launcher extends Application {
public static void main(String[] args) {
Application.launch();
}
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/main.fxml"));
primaryStage.setTitle("PDF test app");
primaryStage.setScene(new Scene(root, 1280, 576));
primaryStage.show();
}
}希望这对某人有帮助。
发布于 2015-10-28 15:25:06
我建议使用PDF JS javascript库。
创建一个WebView并静态加载此javascript查看器示例项目的html/javascript内容。在javascript中创建一个函数,您可以向其发送要显示的pdf字节数组。
这样,pdf查看器的所有逻辑都已经存在了。您甚至可以修改查看器html以删除那里的一些特性。
另外,要小心JPedalFX,因为我发现它在必须呈现被添加到pdf文件中的图像时不可靠。在我的例子中,JPedalFX无法呈现由jfreechart生成的图表图像。
https://stackoverflow.com/questions/18207116
复制相似问题