24

我遇到了这个错误:

java.lang.UnsupportedOperationException:当前平台不支持桌面 API

我会从我的 java 应用程序中打开一个文件。我使用这种方法:

Desktop.getDesktop().open(new File(report.html"));

我怎么解决这个问题?

4

4 回答 4

53

基本上,问题在于 Java 桌面集成在 Linux 上不能很好地工作。

它旨在与 Windows 很好地配合使用;有些东西在其他系统上有效,但没有人真正关心为这些系统添加适当的支持。即使您安装了所需的“gnome 库”,结果也会很差。

不久前我遇到了同样的问题,并提出了下面的课程。

该目标是通过使用系统特定的命令来实现的:

KDE:     kde-open
GNOME:   gnome-open
Any X-server system: xdg-open
MAC:     open
Windows: explorer

如果这些都不起作用,它会尝试 Java Desktop 提供的实现。
因为这个通常会失败,所以它被尝试作为最后的手段。


DesktopApi 类

此类提供静态方法open和. 它经过测试可在 Linux(Kde 和 Gnome)、Windows 和 Mac 上运行。browseedit

如果你使用它,请给我信用。

package net.mightypork.rpack.utils;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;


public class DesktopApi {

    public static boolean browse(URI uri) {

        if (openSystemSpecific(uri.toString())) return true;

        if (browseDESKTOP(uri)) return true;

        return false;
    }


    public static boolean open(File file) {

        if (openSystemSpecific(file.getPath())) return true;

        if (openDESKTOP(file)) return true;

        return false;
    }


    public static boolean edit(File file) {

        // you can try something like
        // runCommand("gimp", "%s", file.getPath())
        // based on user preferences.

        if (openSystemSpecific(file.getPath())) return true;

        if (editDESKTOP(file)) return true;

        return false;
    }


    private static boolean openSystemSpecific(String what) {

        EnumOS os = getOs();

        if (os.isLinux()) {
            if (runCommand("kde-open", "%s", what)) return true;
            if (runCommand("gnome-open", "%s", what)) return true;
            if (runCommand("xdg-open", "%s", what)) return true;
        }

        if (os.isMac()) {
            if (runCommand("open", "%s", what)) return true;
        }

        if (os.isWindows()) {
            if (runCommand("explorer", "%s", what)) return true;
        }

        return false;
    }


    private static boolean browseDESKTOP(URI uri) {

        logOut("Trying to use Desktop.getDesktop().browse() with " + uri.toString());
        try {
            if (!Desktop.isDesktopSupported()) {
                logErr("Platform is not supported.");
                return false;
            }

            if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
                logErr("BROWSE is not supported.");
                return false;
            }

            Desktop.getDesktop().browse(uri);

            return true;
        } catch (Throwable t) {
            logErr("Error using desktop browse.", t);
            return false;
        }
    }


    private static boolean openDESKTOP(File file) {

        logOut("Trying to use Desktop.getDesktop().open() with " + file.toString());
        try {
            if (!Desktop.isDesktopSupported()) {
                logErr("Platform is not supported.");
                return false;
            }

            if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
                logErr("OPEN is not supported.");
                return false;
            }

            Desktop.getDesktop().open(file);

            return true;
        } catch (Throwable t) {
            logErr("Error using desktop open.", t);
            return false;
        }
    }


    private static boolean editDESKTOP(File file) {

        logOut("Trying to use Desktop.getDesktop().edit() with " + file);
        try {
            if (!Desktop.isDesktopSupported()) {
                logErr("Platform is not supported.");
                return false;
            }

            if (!Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
                logErr("EDIT is not supported.");
                return false;
            }

            Desktop.getDesktop().edit(file);

            return true;
        } catch (Throwable t) {
            logErr("Error using desktop edit.", t);
            return false;
        }
    }


    private static boolean runCommand(String command, String args, String file) {

        logOut("Trying to exec:\n   cmd = " + command + "\n   args = " + args + "\n   %s = " + file);

        String[] parts = prepareCommand(command, args, file);

        try {
            Process p = Runtime.getRuntime().exec(parts);
            if (p == null) return false;

            try {
                int retval = p.exitValue();
                if (retval == 0) {
                    logErr("Process ended immediately.");
                    return false;
                } else {
                    logErr("Process crashed.");
                    return false;
                }
            } catch (IllegalThreadStateException itse) {
                logErr("Process is running.");
                return true;
            }
        } catch (IOException e) {
            logErr("Error running command.", e);
            return false;
        }
    }


    private static String[] prepareCommand(String command, String args, String file) {

        List<String> parts = new ArrayList<String>();
        parts.add(command);

        if (args != null) {
            for (String s : args.split(" ")) {
                s = String.format(s, file); // put in the filename thing

                parts.add(s.trim());
            }
        }

        return parts.toArray(new String[parts.size()]);
    }

    private static void logErr(String msg, Throwable t) {
        System.err.println(msg);
        t.printStackTrace();
    }

    private static void logErr(String msg) {
        System.err.println(msg);
    }

    private static void logOut(String msg) {
        System.out.println(msg);
    }

    public static enum EnumOS {
        linux, macos, solaris, unknown, windows;

        public boolean isLinux() {

            return this == linux || this == solaris;
        }


        public boolean isMac() {

            return this == macos;
        }


        public boolean isWindows() {

            return this == windows;
        }
    }


    public static EnumOS getOs() {

        String s = System.getProperty("os.name").toLowerCase();

        if (s.contains("win")) {
            return EnumOS.windows;
        }

        if (s.contains("mac")) {
            return EnumOS.macos;
        }

        if (s.contains("solaris")) {
            return EnumOS.solaris;
        }

        if (s.contains("sunos")) {
            return EnumOS.solaris;
        }

        if (s.contains("linux")) {
            return EnumOS.linux;
        }

        if (s.contains("unix")) {
            return EnumOS.linux;
        } else {
            return EnumOS.unknown;
        }
    }
}
于 2013-08-01T20:53:03.447 回答
15

我正在使用带有 Oracle jdk1.6.0_45 的 Ubuntu 12.04 LTS 64 位并且遇到了同样的问题。我正在运行 gnome-classic 作为桌面而不是 Unity。这对我有用:

sudo apt-get install libgnome2-0

安装此软件包后,我重新启动了我的 Java Swing 应用程序并且Desktop.getDesktop().open(new File("myfile"));工作正常。

于 2013-11-05T18:17:33.960 回答
7

并非所有系统都支持 Desktop 类。

来自 Java Swing 教程How to Integrate with the Desktop Class

使用 isDesktopSupported() 方法来确定桌面 API 是否可用。在 Solaris 操作系统和 Linux 平台上,此 API 依赖于 Gnome 库。如果这些库不可用,此方法将返回 false。在确定支持 Desktop API 后,即 isDesktopSupported() 返回 true,应用程序可以使用静态方法 getDesktop() 检索 Desktop 实例。

无论如何,如果不支持桌面,最好提供另一种打开文件的方法。

于 2013-08-01T20:57:47.010 回答
1

支持因各种 JDK 上的实现而异。我在使用 OpenJDK 1.7.0 时遇到了“UnsupportedOperationException”。切换到 Oracle JDK 1.7 有效。

在可行的情况下,您可以切换 JDK 或建议您的用户切换 JDK 以启用某个功能。

于 2013-10-21T00:14:41.893 回答