javafx - 当 Jasper Report 在弹出窗口中可见时如何在 JavaFx 中锁定父窗口
问题描述
为了在 JavaFX 11 中创建 Jasper 报告,我正在使用动态报告。当我单击按钮 Jasper Report 打开并在弹出窗口中可见时。但是我可以根据需要多次单击该按钮,并且报告将打开这些次数。但是一旦jasper报告可见,我想锁定父窗口,以便只有在关闭弹出窗口后才能访问父窗口。正如这个问题中所解释的,我们可以在父窗口和子窗口中实现同样的事情,但我想用 Parent 来实现类似的事情,因为我的舞台和孩子是 Jasper Window。下面提到了相同的代码: -
JavaFxJasperReportsDemo.java
package demo;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.application.Platform;
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.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;
public class JavaFxJasperReportsDemo extends Application{
@FXML
private StackPane stackPane;
public void start(Stage stage) throws Exception{
try{
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 {
report.show(false);
} catch (DRException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
try{
launch(args);
}
catch (Exception e){
e.printStackTrace();
}
}
}
解决方案
到目前为止,我还没有基于父窗口“可达性”的解决方案。但我可以为您提供一个替代解决方案,不允许用户多次单击。这个想法是在您按下按钮后立即禁用场景的根节点,并仅在报告窗口关闭时启用它。不确定这是否符合您的目的。
reportButton.setOnAction(e -> {
// Get root node of the scene
Node sceneRoot = ((Node)e.getTarget()).getScene().getRoot();
// First things first, disable it !!
sceneRoot.setDisable(true);
// Your actual method for showing report
loadReport(e);
// Get all current AWT windows.
java.awt.Window[] windows = java.awt.Window.getWindows();
// Get the recently added window (your report window) and add a close listener.
windows[windows.length-1].addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
// When the window is closed, enable your root node.
sceneRoot.setDisable(false);
}
});
});
注意:JasperReportBuilder 的 JasperViewer 的内部实现是一个 JFrame。
[更新]
完整的工作演示如下:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
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.HorizontalAlignment;
import net.sf.dynamicreports.report.exception.DRException;
import java.util.ArrayList;
import java.util.List;
public class JavaFxJasperReportsDemo extends Application {
@FXML
private StackPane stackPane;
public void start(Stage stage) throws Exception {
try {
StackPane root = new StackPane();
ContextMenu cm = new ContextMenu();
cm.getItems().addAll(new MenuItem("Test1"), new MenuItem("Test2"));
Button reportButton = new Button("Report");
reportButton.setContextMenu(cm);
reportButton.setOnAction(e -> {
// Get root node of the scene
Node sceneRoot = ((Node) e.getTarget()).getScene().getRoot();
// First things first, disable it !!
sceneRoot.setDisable(true);
// Your actual method for showing report
loadReport(e);
// Get all current AWT windows.
java.awt.Window[] windows = java.awt.Window.getWindows();
// Get the recently added window (your report window) and add a listener.
windows[windows.length - 1].addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
// When the window is closed, enable your root node.
sceneRoot.setDisable(false);
}
});
});
root.getChildren().add(reportButton);
Scene scene = new Scene(root, 200, 200);
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("City 1");
lstDemoPOJOs.add(demoPOJO);
demoPOJO = new DemoPOJO();
demoPOJO.setName("XYZ");
demoPOJO.setCity("City 2");
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").
setHorizontalAlignment(HorizontalAlignment.CENTER))
//.pageFooter(Components.pageXofY())
.setDataSource(lstDemoPOJOs);
try {
report.show(false);
} catch (DRException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
launch(args);
} catch (Exception e) {
e.printStackTrace();
}
}
}
推荐阅读
- reactjs - 在 ReactJS 中生成站点地图,当前可用的解决方案不起作用
- python-3.x - ImportError:无法使用 pytesseract 导入名称“image_to_data”
- c# - 如何使用 VS2017 查看长时间运行的 C# 异步操作的当前进度?
- c++ - 你如何在静态函数c ++中使用成员函数
- android - ibm watson 和谷歌云语音到文本 api 是否有可能结合?
- java - 构建失败的 android,弃用的功能
- vue.js - 捏放大vue js
- docker - 使用 docker-compose 构建开发和部署管道
- xamarin.forms - 如何在 Xamarin 中更改 MasterMainPage 的导航栏颜色
- r - 按时间顺序排序带时间戳的数据时出现不希望的输出