2008-11-28 38 views
11

我正在使用Java 1.5,我想啓動關聯的應用程序來打開文件。我知道Java 1.6引入了Desktop API,但我需要一個解決方案,用於Java 1.5使用Java 1.5跨平臺打開文件的方式

到目前爲止,我發現了一個辦法做到這一點在Windows:

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

是否有一個跨平臺的方式做到這一點?或者至少有類似的解決方案Linux

回答

11

+1 this answer

此外,我會使用多態提示如下實施。

客戶端代碼:

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)但讓我們假設每個方法都是以特定於平臺的方式執行另一個步驟。

做這種方法可能會刪除不需要的if/elseif/else結構會隨着時間的推移而引入錯誤(如果代碼中有6個這樣的變化,而且有變化,您可能會忘記更新其中的一個,或者通過複製/粘貼,您可能會忘記更改要執行的命令)

4

SWT使您lokk的標準程序來打開通過文件的可能性:

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

嚴格,因爲SWT是平臺相關的,這不是跨平臺的,但對於每一個平臺,你可以使用不同的SWT罐子。

+0

注意:Program.java的源代碼在http://kickjava.com/src/org/eclipse/swt/program/Program.java.htm。可能也會有所幫助 – VonC 2008-11-28 09:15:13

+0

對於Java 1.5 + SWT用戶來說這可能非常有用。但僅僅使用SWT可能不是最佳選擇。 – asalamon74 2008-11-28 21:26:00

0

您可以使用操作系統的默認方式爲您打開它。

  • 的Windows:「CMD/C 文件名
  • Linux的瓦特/ GNOME 「侏儒開
  • 的Linux w ^/KDE ??
  • OSX 「開放
12
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"); 
} 

and

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)); 
    } 
+0

你也可以採用多態。這樣你可以增加實施的靈活性。然後,您可以避免在下一個操作中使用另一個if/elseif/else鏈。 – OscarRyz 2008-11-28 17:37:42

+0

你應該使用`xdg-open`而不是`gnome-open`或`kfmclient`或其他類型,所以它在xfce或其他環境中工作得更好。 – 2008-11-29 00:23:40

12

JDIC是一個在Java 1.5中提供類似桌面功能的庫。

這樣就可以通過減少類之間的耦合增加新的平臺更加容易:

+1

這個庫似乎解決了這個問題。我不明白爲什麼人們投票重新發明輪... – 2010-04-23 15:28:11

-3

我們確實將該命令放在配置文件的某處。

您的「JAR和源代碼」將是「跨平臺」的,但您的部署不會。

你也可以做點像this answer。您可以將「Deskop」實現的工廠類的類名放入安裝文件中。 (如果你喜歡,可以是導遊或春遊)

5

就像一個加法:而不是gnome-open,使用xdg-open。它是XdgUtils的一部分,而它又是LSB Desktop支持包(從3.2開始)的一部分。

您可以(應該)仍然使用gnome-open作爲回退,但xdg-open也適用於非GNOME桌面。

0

另一個答案(boutta)建議使用SWT。我不會推薦引用僅爲此庫,但如果你已經在使用它,只需執行:

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

注意到,這種方法只會工作(並返回true)如果Display對象已已創建(例如通過創建一個Shell)。還要注意它必須在主線程中運行;例如: -

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

在上面我已經推出了網址,但啓動文件相同的方式工作的例子。