-
Bug
-
Resolution: Cannot Reproduce
-
P4
-
None
-
jfx17
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
Windows 10 / JDK 17 ea 31 / openjfx-17-ea+15/ Open JDK 64 Bit Server VM (build 17-ea+31-2664, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
In Windows 10 with JDK 17-ea+15 but also with others JDK from 8 to 17 when i call the Method showPrintDialog in the Class PrinterJob in package package javafx.print is not working.
Dialog will not appear but the returned boolean is always true.
Reason is a flag headless (java.awt.headless) which in Spring is true initialized.
In the Implementation in Java Class J2DPrinterJob we have:
public boolean showPrintDialog(Window owner) {
if (jobRunning || jobDone) {
return false;
}
if (GraphicsEnvironment.isHeadless()) {
return true;
}
Returning true to the call of the method showPrintDialog and not printing the dialog if the application is headless.
In my Opinion the bug should be repair just with a return false, because if i run the application with a headless modus and call the showPrintdialog it should not be possible and not return a true.
Or at least throw an Exception.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a Springboot Project in https://start.spring.io/ with maven, java and packaging jar. Version doesnt matter.
2. Change pom to include a JavaFX project.
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17-ea+15</version>
</dependency>
and under plugin
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<!-- Default configuration for running -->
<!-- Usage: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.example.javafxprintdialog.JavafxprintdialogApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
3. In der Main Class, overried the start method with the next Snip:
package com.example.javafxprintdialog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
@SpringBootApplication
public class JavafxprintdialogApplication extends Application {
private Label jobStatus;
@Autowired
public JavafxprintdialogApplication() {
this.jobStatus = new Label();
}
public static void main(String[] args) {
SpringApplication.run(JavafxprintdialogApplication.class, args);
Application.launch(args);
}
@Override
public void start(final Stage stage) {
// Create the Text Label
Label textLabel = new Label("Please insert your Text:");
// Create the TextArea
final TextArea textArea = new TextArea();
// Create the Buttons
Button pageSetupButton = new Button("Page Setup and Print");
// Create the Event-Handlers for the Button
pageSetupButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
pageSetup(textArea, stage);
}
});
// Create the Status Box
HBox jobStatusBox = new HBox(5, new Label("Job Status: "), jobStatus);
// Create the Button Box
HBox buttonBox = new HBox(pageSetupButton);
// Create the VBox
VBox root = new VBox(5);
// Add the Children to the VBox
root.getChildren().addAll(textLabel, textArea, buttonBox, jobStatusBox);
// Set the Size of the VBox
root.setPrefSize(400, 300);
// Set the Style-properties of the VBox
root.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-insets: 5;" +
"-fx-border-radius: 5;" +
"-fx-border-color: #ffffff;");
// Create the Scene
Scene scene = new Scene(root);
// Add the scene to the Stage
stage.setScene(scene);
// Set the title of the Stage
stage.setTitle("A Printing Dialog Example");
// Display the Stage
stage.show();
}
private void pageSetup(Node node, Stage owner) {
// Create the PrinterJob
PrinterJob job = PrinterJob.createPrinterJob();
if (job == null) {
return;
}
// Show the page setup dialog
Platform.runLater(() -> showpagesetupdialog(node, owner, job));
}
private void showpagesetupdialog(Node node, Stage owner, PrinterJob job) {
System.out.println("Printer:" + job.getPrinter().toString());
System.out.println("Settings:" + job.getJobSettings().toString());
boolean proceed = job.showPageSetupDialog(owner.getScene().getWindow());
if (proceed) {
print(job, node);
}
}
private void print(PrinterJob job, Node node) {
// Set the Job Status Message
jobStatus.textProperty().bind(job.jobStatusProperty().asString());
// Print the node
boolean printed = job.printPage(node);
if (printed) {
job.endJob();
}
}
}
4. run mvn clean install javafx:run
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
boolean should be false if the showPrintDialog doesnt appear.
ACTUAL -
boolean result of the method showPrintDialog is true but the Dialog is not appearing.
---------- BEGIN SOURCE ----------
package com.example.javafxprintdialog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
@SpringBootApplication
public class JavafxprintdialogApplication extends Application {
private Label jobStatus;
@Autowired
public JavafxprintdialogApplication() {
this.jobStatus = new Label();
}
public static void main(String[] args) {
SpringApplication.run(JavafxprintdialogApplication.class, args);
Application.launch(args);
}
@Override
public void start(final Stage stage) {
// Create the Text Label
Label textLabel = new Label("Please insert your Text:");
// Create the TextArea
final TextArea textArea = new TextArea();
// Create the Buttons
Button pageSetupButton = new Button("Page Setup and Print");
// Create the Event-Handlers for the Button
pageSetupButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
pageSetup(textArea, stage);
}
});
// Create the Status Box
HBox jobStatusBox = new HBox(5, new Label("Job Status: "), jobStatus);
// Create the Button Box
HBox buttonBox = new HBox(pageSetupButton);
// Create the VBox
VBox root = new VBox(5);
// Add the Children to the VBox
root.getChildren().addAll(textLabel, textArea, buttonBox, jobStatusBox);
// Set the Size of the VBox
root.setPrefSize(400, 300);
// Set the Style-properties of the VBox
root.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-insets: 5;" +
"-fx-border-radius: 5;" +
"-fx-border-color: #ffffff;");
// Create the Scene
Scene scene = new Scene(root);
// Add the scene to the Stage
stage.setScene(scene);
// Set the title of the Stage
stage.setTitle("A Printing Dialog Example");
// Display the Stage
stage.show();
}
private void pageSetup(Node node, Stage owner) {
// Create the PrinterJob
PrinterJob job = PrinterJob.createPrinterJob();
if (job == null) {
return;
}
// Show the page setup dialog
Platform.runLater(() -> showpagesetupdialog(node, owner, job));
}
private void showpagesetupdialog(Node node, Stage owner, PrinterJob job) {
System.out.println("Printer:" + job.getPrinter().toString());
System.out.println("Settings:" + job.getJobSettings().toString());
boolean proceed = job.showPageSetupDialog(owner.getScene().getWindow());
if (proceed) {
print(job, node);
}
}
private void print(PrinterJob job, Node node) {
// Set the Job Status Message
jobStatus.textProperty().bind(job.jobStatusProperty().asString());
// Print the node
boolean printed = job.printPage(node);
if (printed) {
job.endJob();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Setting the default headless to false in Spring with:
SpringApplicationBuilder builder = new SpringApplicationBuilder(App.class);
builder.headless(false).run(args);
will show the dialog
FREQUENCY : always
Windows 10 / JDK 17 ea 31 / openjfx-17-ea+15/ Open JDK 64 Bit Server VM (build 17-ea+31-2664, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
In Windows 10 with JDK 17-ea+15 but also with others JDK from 8 to 17 when i call the Method showPrintDialog in the Class PrinterJob in package package javafx.print is not working.
Dialog will not appear but the returned boolean is always true.
Reason is a flag headless (java.awt.headless) which in Spring is true initialized.
In the Implementation in Java Class J2DPrinterJob we have:
public boolean showPrintDialog(Window owner) {
if (jobRunning || jobDone) {
return false;
}
if (GraphicsEnvironment.isHeadless()) {
return true;
}
Returning true to the call of the method showPrintDialog and not printing the dialog if the application is headless.
In my Opinion the bug should be repair just with a return false, because if i run the application with a headless modus and call the showPrintdialog it should not be possible and not return a true.
Or at least throw an Exception.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a Springboot Project in https://start.spring.io/ with maven, java and packaging jar. Version doesnt matter.
2. Change pom to include a JavaFX project.
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17-ea+15</version>
</dependency>
and under plugin
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<!-- Default configuration for running -->
<!-- Usage: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.example.javafxprintdialog.JavafxprintdialogApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
3. In der Main Class, overried the start method with the next Snip:
package com.example.javafxprintdialog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
@SpringBootApplication
public class JavafxprintdialogApplication extends Application {
private Label jobStatus;
@Autowired
public JavafxprintdialogApplication() {
this.jobStatus = new Label();
}
public static void main(String[] args) {
SpringApplication.run(JavafxprintdialogApplication.class, args);
Application.launch(args);
}
@Override
public void start(final Stage stage) {
// Create the Text Label
Label textLabel = new Label("Please insert your Text:");
// Create the TextArea
final TextArea textArea = new TextArea();
// Create the Buttons
Button pageSetupButton = new Button("Page Setup and Print");
// Create the Event-Handlers for the Button
pageSetupButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
pageSetup(textArea, stage);
}
});
// Create the Status Box
HBox jobStatusBox = new HBox(5, new Label("Job Status: "), jobStatus);
// Create the Button Box
HBox buttonBox = new HBox(pageSetupButton);
// Create the VBox
VBox root = new VBox(5);
// Add the Children to the VBox
root.getChildren().addAll(textLabel, textArea, buttonBox, jobStatusBox);
// Set the Size of the VBox
root.setPrefSize(400, 300);
// Set the Style-properties of the VBox
root.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-insets: 5;" +
"-fx-border-radius: 5;" +
"-fx-border-color: #ffffff;");
// Create the Scene
Scene scene = new Scene(root);
// Add the scene to the Stage
stage.setScene(scene);
// Set the title of the Stage
stage.setTitle("A Printing Dialog Example");
// Display the Stage
stage.show();
}
private void pageSetup(Node node, Stage owner) {
// Create the PrinterJob
PrinterJob job = PrinterJob.createPrinterJob();
if (job == null) {
return;
}
// Show the page setup dialog
Platform.runLater(() -> showpagesetupdialog(node, owner, job));
}
private void showpagesetupdialog(Node node, Stage owner, PrinterJob job) {
System.out.println("Printer:" + job.getPrinter().toString());
System.out.println("Settings:" + job.getJobSettings().toString());
boolean proceed = job.showPageSetupDialog(owner.getScene().getWindow());
if (proceed) {
print(job, node);
}
}
private void print(PrinterJob job, Node node) {
// Set the Job Status Message
jobStatus.textProperty().bind(job.jobStatusProperty().asString());
// Print the node
boolean printed = job.printPage(node);
if (printed) {
job.endJob();
}
}
}
4. run mvn clean install javafx:run
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
boolean should be false if the showPrintDialog doesnt appear.
ACTUAL -
boolean result of the method showPrintDialog is true but the Dialog is not appearing.
---------- BEGIN SOURCE ----------
package com.example.javafxprintdialog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
@SpringBootApplication
public class JavafxprintdialogApplication extends Application {
private Label jobStatus;
@Autowired
public JavafxprintdialogApplication() {
this.jobStatus = new Label();
}
public static void main(String[] args) {
SpringApplication.run(JavafxprintdialogApplication.class, args);
Application.launch(args);
}
@Override
public void start(final Stage stage) {
// Create the Text Label
Label textLabel = new Label("Please insert your Text:");
// Create the TextArea
final TextArea textArea = new TextArea();
// Create the Buttons
Button pageSetupButton = new Button("Page Setup and Print");
// Create the Event-Handlers for the Button
pageSetupButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
pageSetup(textArea, stage);
}
});
// Create the Status Box
HBox jobStatusBox = new HBox(5, new Label("Job Status: "), jobStatus);
// Create the Button Box
HBox buttonBox = new HBox(pageSetupButton);
// Create the VBox
VBox root = new VBox(5);
// Add the Children to the VBox
root.getChildren().addAll(textLabel, textArea, buttonBox, jobStatusBox);
// Set the Size of the VBox
root.setPrefSize(400, 300);
// Set the Style-properties of the VBox
root.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-insets: 5;" +
"-fx-border-radius: 5;" +
"-fx-border-color: #ffffff;");
// Create the Scene
Scene scene = new Scene(root);
// Add the scene to the Stage
stage.setScene(scene);
// Set the title of the Stage
stage.setTitle("A Printing Dialog Example");
// Display the Stage
stage.show();
}
private void pageSetup(Node node, Stage owner) {
// Create the PrinterJob
PrinterJob job = PrinterJob.createPrinterJob();
if (job == null) {
return;
}
// Show the page setup dialog
Platform.runLater(() -> showpagesetupdialog(node, owner, job));
}
private void showpagesetupdialog(Node node, Stage owner, PrinterJob job) {
System.out.println("Printer:" + job.getPrinter().toString());
System.out.println("Settings:" + job.getJobSettings().toString());
boolean proceed = job.showPageSetupDialog(owner.getScene().getWindow());
if (proceed) {
print(job, node);
}
}
private void print(PrinterJob job, Node node) {
// Set the Job Status Message
jobStatus.textProperty().bind(job.jobStatusProperty().asString());
// Print the node
boolean printed = job.printPage(node);
if (printed) {
job.endJob();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Setting the default headless to false in Spring with:
SpringApplicationBuilder builder = new SpringApplicationBuilder(App.class);
builder.headless(false).run(args);
will show the dialog
FREQUENCY : always