3

im using java.awt.print.PrinterJob.printDialog() to start a printDialog in a javafx Application. Running on os-x i always get a java.awt.HeadlessException from the printDialog() method.

I've already read that javafx8 supports its own printingdialogs but unfortunately i can't switch to javafx8 in this project.

Any ideas how to solve this?

Patrick Werner
  • 1,106
  • 9
  • 24
  • How are you creating the printer job? From the docs for `HeadlessException`: "Thrown when code that is dependent on a keyboard, display, or mouse is called in an environment that does not support a keyboard, display, or mouse." Have you tested on other environments, and it only happens on OS-X, or is OS-X the only environment you have tested on? – Nathan May 24 '14 at 16:24
  • this problem is related to OSX only. As far as i understand Java FX7 initializes AWT in headless mode in OSX. I've googled some workarounds for this problem, none worked for me. – Patrick Werner May 24 '14 at 19:53
  • http://blog.admadic.com/2013/03/javafx-and-swing-on-mac.html – Patrick Werner May 24 '14 at 20:00

3 Answers3

2

I've written a little class which opens the AWT print dialog from a JavaFX application. I've tested this with JDK 1.8, so I don't know if it helps in your case. Let me know if not, I would then investigate it with JDK 1.7.
[UPDATE] I also works it on JDK1.7 (With integrated JavaFx 2.2) on Mac OS X 10.9.3


import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.Text;

import javax.swing.*;

/**
 * Created by el on 27.05.14.
 */
public class PrintFx {
    private static void initAndShowGUI() {
        // This method is invoked on the EDT thread
        JFrame frame = new JFrame("Swing and JavaFX");
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setSize(300, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                initFX(fxPanel);
            }
        });
    }

    private static void initFX(JFXPanel fxPanel) {
        // This method is invoked on the JavaFX thread
        Scene scene = createScene();
        fxPanel.setScene(scene);
    }

    private static Scene createScene() {
        Group root = new Group();
        Scene scene = new Scene(root, javafx.scene.paint.Color.ALICEBLUE);
        Text text = new Text();

        text.setX(40);
        text.setY(100);
        text.setFont(new Font(25));
        text.setText("Welcome JavaFX!");

        //A button with the specified text caption.
        javafx.scene.control.Button button2 = new javafx.scene.control.Button("Open AWT print dialog");
        button2.setOnAction(new EventHandler() {
            @Override public void handle(ActionEvent e) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("now open dialog!");
                        java.awt.print.PrinterJob.getPrinterJob().printDialog();
                    }
                });
            }
        });

        root.getChildren().add(text);
        root.getChildren().add(button2);

        return (scene);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                initAndShowGUI();
            }
        });
    }
}
elou
  • 1,242
  • 15
  • 21
  • works for me a well. THX. I assume this works because of the the new Thread which is opened for the AWT part? – Patrick Werner Jun 13 '14 at 12:36
  • You're right, the printDialog() could only be called from the EDT (the thread responsible for the AWT actions). No extra thread will be started, the EDT already runs, the runnable is only a 'task' which will be executed by the EDT. – elou Jun 23 '14 at 12:45
1

As Java FX8 was released in the meantime, we switched the project to JavaFX8 and are using PrinterJob job = PrinterJob.createPrinterJob(); http://docs.oracle.com/javase/8/javafx/api/javafx/print/PrinterJob.html

With this new FX8 printing functionality AWT isn't used anymore while creating print jobs -> no Headless Exception.

EDIT: i finally found the workarounds for AWT <-> Java FX which i've found some time ago an couldn't find them anymore: JavaFX screencapture headless exception on OSX

me personally would give the outsourcing the AWT parts to another VM method a try

Community
  • 1
  • 1
Patrick Werner
  • 1,106
  • 9
  • 24
0

I'm working on a Spring Boot + JavaFX project, and this problem happens on AWT and JavaFX PrinterJob.[show]printDialog() because the system property java.awt.headless is true by default.

This is how I was able to work around:

System.setProperty("java.awt.headless", "false");
AndreLDM
  • 2,117
  • 1
  • 18
  • 27