java - Jasper 报告组件在 JavaFX Swing 节点中未正确呈现
问题描述
为了在 JavaFX 11 中创建 Jasper 报告,我正在使用动态报告。我正在 Swing 节点中加载报告,但只有当我单击堆栈窗格区域时才会显示 Jasper 报告,并且只有当我将鼠标悬停在所有这些组件上时才会显示所有其他组件。组件和报告内容不会立即加载,而不是在鼠标悬停时显示,并且在滚动堆栈窗格时显示报告。
因为这是 Java 8 中的错误并且似乎已解决,但在 Java 11 中我也遇到了同样的问题。
更新
由于我没有得到任何响应,并且按照 kleopatra 的建议,我创建了最少的可重现代码。请调查一下。
JavaFxJasperReportsDemo.java
package demo;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.SwingNode;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import net.sf.dynamicreports.jasper.builder.JasperReportBuilder;
import net.sf.dynamicreports.report.builder.DynamicReports;
import net.sf.dynamicreports.report.builder.column.Columns;
import net.sf.dynamicreports.report.builder.component.Components;
import net.sf.dynamicreports.report.builder.datatype.DataTypes;
import net.sf.dynamicreports.report.constant.HorizontalTextAlignment;
import net.sf.dynamicreports.report.exception.DRException;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.swing.JRViewer;
public class JavaFxJasperReportsDemo extends Application{
@FXML
private StackPane stackPane;
public void start(Stage stage) throws Exception{
try{
System.out.println("Hello");
Parent root = FXMLLoader.load(getClass().getResource("/FXMLJavaFXJasperReportsDemo.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Java FX Demo");
stage.show();
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent arg0) {
Platform.exit();
}
});
}
catch (Exception e){
throw e;
}
}
@FXML
public void loadReport(ActionEvent event) {
JasperReportBuilder report = DynamicReports.report();
List<DemoPOJO> lstDemoPOJOs=new ArrayList<DemoPOJO>();
DemoPOJO demoPOJO=new DemoPOJO();
demoPOJO.setName("ABC");
demoPOJO.setCity("Delhi");
lstDemoPOJOs.add(demoPOJO);
demoPOJO = new DemoPOJO();
demoPOJO.setName("XYZ");
demoPOJO.setCity("Agra");
lstDemoPOJOs.add(demoPOJO);
report
.columns(
Columns.columnRowNumberColumn("S No"),
Columns.column("Name", "name", DataTypes.stringType()),
Columns.column("Address", "city", DataTypes.stringType())
).title(
Components.text("Demo Java Fx Jasper Reports").
setHorizontalTextAlignment(HorizontalTextAlignment.CENTER))
.pageFooter(Components.pageXofY())
.setDataSource(lstDemoPOJOs);
try {
JasperPrint jasperPrintReport=report.toJasperPrint();
SwingNode swingNode = new SwingNode();
AnchorPane.setTopAnchor(swingNode,0.0);
AnchorPane.setBottomAnchor(swingNode,0.0);
AnchorPane.setLeftAnchor(swingNode,0.0);
AnchorPane.setRightAnchor(swingNode,0.0);
JRViewer jrViewer= new JRViewer(jasperPrintReport);
SwingUtilities.invokeLater(() ->swingNode.setContent(jrViewer)
);
stackPane.getChildren().add(swingNode);
} catch (DRException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
System.out.println("Hello Main");
try{
launch(args);
}
catch (Exception e){
e.printStackTrace();
}
}
}
演示POJO.java
package demo;
public class DemoPOJO {
String name;
String city;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
FXMLJavaFXJasperReportsDemo.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.StackPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="561.0" prefWidth="745.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="demo.JavaFxJasperReportsDemo">
<children>
<Label layoutX="345.0" layoutY="24.0" text="Java FX Demo Application" />
<StackPane fx:id="stackPane" layoutX="14.0" layoutY="120.0" prefHeight="392.0" prefWidth="722.0" />
<Button layoutX="62.0" layoutY="68.0" mnemonicParsing="false" onAction="#loadReport" text="Load Report" />
</children>
</AnchorPane>
我正在使用的依赖项是:-
<dependency>
<groupId>net.sourceforge.dynamicreports</groupId>
<artifactId>dynamicreports-core</artifactId>
<version>6.1.0</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>11-ea+24</version>
</dependency>
输出
解决方案
在检查 OpenJDK wiki 中的OpenJFX 调试标志后,您可以尝试以下操作。
pom.xml
添加OpenJFX 的 JVM 选项的构建部分
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.4</version>
<configuration>
<mainClass>demo.JavaFxJasperReportsDemo</mainClass>
<options>
<option>-Dprism.verbose=true</option>
</options>
</configuration>
</plugin>
使用它执行应用程序mvn javafx:run
将报告检测到的 Prism 配置
在我的系统上输出
Prism pipeline init order: es2 sw
Using Double Precision Marlin Rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
Prism pipeline name = com.sun.prism.es2.ES2Pipeline
Loading ES2 native library ... prism_es2
succeeded.
GLFactory using com.sun.prism.es2.X11GLFactory
(X) Got class = class com.sun.prism.es2.ES2Pipeline
Initialized prism pipeline: com.sun.prism.es2.ES2Pipeline
...
Graphics Vendor: Intel Open Source Technology Center
Renderer: Mesa DRI Intel(R) Ivybridge Mobile
Version: 3.0 Mesa 19.3.2
它使用的是硬件加速渲染器Loading ES2 native library ... prism_es2
可以强制使用软件渲染器。中的变化pom.xml
<options>
<option>-Dprism.verbose=true</option>
<option>-Dprism.order=sw</option
</options>
然后输出是
Prism pipeline init order: sw
Using Double Precision Marlin Rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
*** Fallback to Prism SW pipeline
Prism pipeline name = com.sun.prism.sw.SWPipeline
(X) Got class = class com.sun.prism.sw.SWPipeline
Initialized prism pipeline: com.sun.prism.sw.SWPipeline
vsync: true vpipe: false
它正在使用软件渲染器Fallback to Prism SW pipeline
。
用于上述测试的版本:
JDK
java version "11.0.2" 2019-01-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode)
马文
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
推荐阅读
- sql - 为什么要求我输入参数值?微软访问 SQL
- reactjs - 当我尝试从 API 响应访问 json 数据时,“属性不存在于类型‘从不’上”
- python-3.x - Python + Firestore:从集合中的所有文档中查询特定字段
- android - Android中的请求队列
- vim - 终端调整大小后重置vim的布局
- python - 如何在熊猫数据框中将对象 dtype 列转换为 int16?
- java - Jython 使用 kryonet 注册课程
- python - 如何使用正则表达式对该字符串进行排序
- swift - Xcode 无法构建新项目 (12.4) - 无法构建 Objective-C 模块“SwiftUI”
- android - android studio - 我在下载时不小心点击了“背景”按钮,现在我找不到下载进度