JavaFX2: 在使用java.awt.print.PrinterJob.printDialog()时出现HeadlessException

3

我正在使用java.awt.print.PrinterJob.printDialog()在JavaFX应用程序中启动打印对话框。在OS-X上运行时,我总是从printDialog()方法中得到一个java.awt.HeadlessException。

我已经了解到javafx8支持自己的打印对话框,但不幸的是我无法在这个项目中切换到javafx8。

有什么想法可以解决这个问题吗?


你是如何创建打印作业的?根据HeadlessException文档所述:“当在不支持键盘、显示器或鼠标的环境中调用依赖于键盘、显示器或鼠标的代码时,会抛出此异常。” 你是否在其他环境上进行了测试,只有在OS-X上才发生问题,还是你只在OS-X上进行了测试? - Nathan
这个问题只与OSX有关。据我了解,Java FX7在OSX中以无头模式初始化AWT。我已经搜索了一些解决此问题的方法,但都没有成功。 - Patrick Werner
http://blog.admadic.com/2013/03/javafx-and-swing-on-mac.html - Patrick Werner
3个回答

2

我写了一个小类,可以在JavaFX应用程序中打开AWT打印对话框。 我已经在JDK 1.8上测试过,所以不知道它是否适用于您的情况。 如果不行,请告诉我,我会尝试在JDK 1.7上进行调查。
[更新] 我还在Mac OS X 10.9.3上使用集成的JavaFx 2.2测试通过了JDK1.7。


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();
            }
        });
    }
}

我认为这个能够工作是因为为AWT部分开启了一个新的线程?对吧。 - Patrick Werner
你是对的,printDialog() 只能从 EDT(负责 AWT 操作的线程)中调用。 不会启动额外的线程,EDT 已经在运行,runnable 只是一个“任务”,将由 EDT 执行。 - elou

1
由于Java FX8已经发布,我们将项目切换到JavaFX8,并使用PrinterJob job = PrinterJob.createPrinterJob(); http://docs.oracle.com/javase/8/javafx/api/javafx/print/PrinterJob.html 进行打印。
通过这种新的FX8打印功能,在创建打印作业时不再使用AWT,因此不会出现Headless Exception。
编辑:我最终找到了一些时间前发现的AWT <-> Java FX的解决方法JavaFX screencapture headless exception on OSX 个人而言,我会尝试将AWT部分外包给另一个VM方法。

感谢您的更新@elnin0,但我们不能切换到JavaFX 8,正在等待另一个答案。 - Robin Jonsson
我已经更新了我的答案,并附上了一些时间前发现的解决方法。 - Patrick Werner

0

我正在开发一个 Spring Boot + JavaFX 项目,遇到了关于 AWT 和 JavaFX PrinterJob.[show]printDialog() 的问题,因为系统属性 java.awt.headless 默认为 true。

以下是我的解决方法:

System.setProperty("java.awt.headless", "false");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接