OSX上的JavaFX screencapture无头异常

我正在将我的旧Java应用程序从swing转换为javafx,我遇到了一个问题.

我正在使用以下代码来捕获屏幕截图:

 public ScreenCapper() {
    ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    gs = ge.getScreenDevices();

    try {
        robot = new Robot(gs[gs.length-1]);
    } catch (AWTException e) {
        LOGGER.getInstance().ERROR("Error creating screenshot robot instance!");
    }
}

public Color capture() {
    Rectangle bounds;

    mode = gs[0].getDisplayMode();
    bounds = new Rectangle(0, 0, mode.getWidth(), mode.getHeight());
    //......
}

这在Windows下运行应用程序时工作正常.但是,在OSX下运行时会出现以下异常:

Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.awt.HeadlessException
at sun.java2d.HeadlessGraphicsEnvironment.getScreenDevices(HeadlessGraphicsEnvironment.java:72)
at be.beeles_place.roggbiv.utils.ScreenCapper.<init>(ScreenCapper.java:33)
at be.beeles_place.roggbiv.modes.AverageColorMode.start(AverageColorMode.java:31)
at be.beeles_place.roggbiv.modes.ColorModeContext.startCurrentColorMode(ColorModeContext.java:28)
at be.beeles_place.roggbiv.controller.RoggbivController.<init>(RoggbivController.java:42)
at be.beeles_place.roggbiv.RoggbivMain.start(RoggbivMain.java:67)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:215)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)

我认为在OSX上显然运行的javafx是无头模式,因为以下调试警告提示:

013-03-10 10:44:03.795 java[1912:5903] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead. 
2013-03-10 10:44:05.472 java[1912:707] [JRSAppKitAWT markAppIsDaemon]: Process manager already initialized: can't fully enable headless mode.

有没有办法让这个工作?或者另一种捕获与OSX不冲突的屏幕截图的方法?

完整代码@ https://github.com/beele/Roggbiv

解决方法:

JavaFX不使用AWT堆栈,因此它不是在纯JavaFX应用程序中启动的.由于线程处理细节,AWT在Mac上以无头模式运行,然后从JavaFX请求.

有下一个选项可以解决这个问题:

>使用一些voodoo魔法来初始化AWT – 在静态初始化中运行java.awt.Toolkit.getDefaultToolkit();编辑这只适用于较旧的JavaFX,对不起
>更好的选择是选择不使用JavaFX中的AWT.您可以使用下一个功能制作屏幕截图:http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#snapshot%28javafx.util.Callback,%20javafx.scene.SnapshotParameters,%20javafx.scene.image.WritableImage%29
>编辑正如亚历山大指出的另一种方法是在一个单独的VM中运行AWT代码.为此,您可以将屏幕截图功能重构为单独的类,并通过以下方式从JavaFX应用程序调用它:

    new ProcessBuilder(
          System.getProperty("java.home") + "/bin/java", 
          "-cp", "classpath", 
          "my.apps.DoScreenshot"
    ).start();

此应用程序可以将屏幕截图存储到文件系统.
如果您需要经常进行屏幕截图并遇到性能问题,您可以运行一次单独的应用程序并通过套接字与其进行通信.
>使用com.sun.glass.ui.Robot而不是AWTRobot

上一篇:使用Java的Robot来按住键


下一篇:java – 在玩家后面创建一条尾随血迹