我使用的是 Java 1.5,我想启动关联的应用程序来打开该文件。我知道Java 1.6引入了 桌面API, ,但我需要一个解决方案 爪哇1.5.

到目前为止,我找到了一种在 Windows 中执行此操作的方法:

Runtime.getRuntime().exec(new String[]{ "rundll32", 
                          "url.dll,FileProtocolHandler", fileName });

有跨平台的方法吗?或者至少有一个类似的解决方案 Linux?

有帮助吗?

解决方案

1为此答案

此外,我建议下面的实现使用多态:

这样,您就可以通过减少类之间的耦合易于添加新的平台。

客户机代码:

 Desktop desktop = Desktop.getDesktop();

 desktop.open( aFile );
 desktop.imaginaryAction( aFile );

台式IMPL:

package your.pack.name;

import java.io.File;

public class Desktop{

    // hide the constructor.
    Desktop(){}

    // Created the appropriate instance
    public static Desktop getDesktop(){

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

        Desktop desktop = new Desktop();
         // This uf/elseif/else code is used only once: here
        if ( os.indexOf("windows") != -1 || os.indexOf("nt") != -1){

            desktop = new WindowsDesktop();

        } else if ( os.equals("windows 95") || os.equals("windows 98") ){

            desktop = new Windows9xDesktop();

        } else if ( os.indexOf("mac") != -1 ) {

            desktop = new OSXDesktop();

        } else if ( os.indexOf("linux") != -1 && isGnome() ) {

            desktop = new GnomeDesktop();

        } else if ( os.indexOf("linux") != -1 && isKde() ) {

            desktop = new KdeDesktop();

        } else {
            throw new UnsupportedOperationException(String.format("The platform %s is not supported ",os) );
        }
        return desktop;
    }

    // default implementation :( 
    public void open( File file ){
        throw new UnsupportedOperationException();
    }

    // default implementation :( 
    public void imaginaryAction( File file  ){
        throw new UnsupportedOperationException();
    }
}

// One subclass per platform below:
// Each one knows how to handle its own platform   


class GnomeDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: execute gnome-open <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec:gnome-something-else <file>
    }

}
class KdeDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: kfmclient exec <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: kfm-imaginary.sh  <file>
    }
}
class OSXDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: open <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: wow!! <file>
    }
}
class WindowsDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: cmd /c start <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: ipconfig /relese /c/d/e
    }
}
class Windows9xDesktop extends Desktop{

    public void open( File file ){
        //Runtime.getRuntime().exec: command.com /C start <file>
    }

    public void imaginaryAction( File file){
       //Runtime.getRuntime().exec: command.com /C otherCommandHere <file>
    }
}

这只是一个例子,在现实生活中是不值得仅创建一个新的类参数化的值(该命令字符串%S),但是让我们想象一下,每个方法执行在特定平台的方式的另一步骤。

做这种做法,可以删除不需要的,如果/ ELSEIF / else结构随时间可能会引入错误(如果代码是这些6和变化是neede,你可能会忘记更新其中的一个,或通过复制/粘贴您可能忘记改变要执行的命令)

其他提示

public static boolean isWindows() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("windows") != -1 || os.indexOf("nt") != -1;
}
public static boolean isMac() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("mac") != -1;
}
public static boolean isLinux() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("linux") != -1;
}
public static boolean isWindows9X() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.equals("windows 95") || os.equals("windows 98");
}

 if (isLinux())
  {
     cmds.add(String.format("gnome-open %s", fileName));
     String subCmd = (exec) ? "exec" : "openURL";
     cmds.add(String.format("kfmclient "+subCmd+" %s", fileName));
  }
  else if (isMac())
  {
     cmds.add(String.format("open %s", fileName));
  }
  else if (isWindows() && isWindows9X())
  {
     cmds.add(String.format("command.com /C start %s", fileName));
  }
  else if (isWindows())
  {
     cmds.add(String.format("cmd /c start %s", fileName));
  }

JDIC 是,在Java中1.5提供桌面样功能的库。

正如加法:与其gnome-open,使用xdg-open。它的 XdgUtils ,这是在LSB的桌面支持包的一部分转部分(从3.2 )。

您可以(应该)仍然使用gnome-open作为后备,但xdg-open也将在非GNOME桌面工作。

SWT 使您lokk为标准程序通过打开一个文件的可能性:

final Program p = Program.findProgram(fileExtension);
p.execute(file.getAbsolutePath());

严格,这不是跨平台的,因为SWT是平台相关的,但对于每一个平台,你可以使用一个diffenrent SWT罐子。

您可以使用操作系统默认的方式为您打开它。

  • 视窗:“命令/c 文件名
  • Linux w/gnome “gnome-open 文件名"
  • Linux 与 Kde ??
  • OSx“打开 文件名"

另一个答案(由boutta)建议使用SWT。我不会推荐引用仅为此库,但如果你已经在使用它,只需执行:

Program.launch("http://google.com/");

必须注意,这种方法只会工作(并返回true)(通过创建一个Display为例),如果Shell对象已经创建。还注意到,它必须在主线程中运行; e.g:

Display.syncExec(new Runnable() {
    public void run() {
        Program.launch("http://google.com/");
    }
});

在上面我已经推出了网址,但启动文件相同的方式工作的例子。

我们真的把命令之外的某处的配置文件中

您“JAR和源代码”将是“跨平台”,但你的部署不会。

您也可以这样做这回答。你可以把工厂类的“Deskop”实施的类名进入安装文件。 (可以是指南或弹簧,如果你喜欢)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top