2008-11-28 37 views
11

Tôi đang sử dụng Java 1.5 và tôi muốn khởi chạy ứng dụng được liên kết để mở tệp. Tôi biết rằng Java 1.6 đã giới thiệu Desktop API, nhưng tôi cần một giải pháp cho Java 1.5.Cách đa nền tảng để mở tệp bằng Java 1.5

Cho đến nay tôi đã tìm ra cách để làm điều đó trong Windows:

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

Có cách nào cross-nền tảng để làm điều đó? Hoặc ít nhất một giải pháp tương tự cho Linux?

Trả lời

11

1 cho this answer

Bên cạnh đó tôi sẽ đề nghị việc thực hiện sau đây sử dụng đa hình:

Bằng cách này bạn có thể thêm nền tảng mới dễ dàng hơn bằng cách giảm khớp nối giữa các lớp.

Mã Chủ đầu tư:

Desktop desktop = Desktop.getDesktop(); 

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

Các impl Desktop:

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> 
    } 
} 

Đây chỉ là một ví dụ, trong cuộc sống thực không phải là giá trị để tạo ra một lớp mới chỉ để parametrize một giá trị (chuỗi lệnh% s) Nhưng hãy tưởng tượng rằng mỗi phương thức thực hiện một bước khác theo cách cụ thể của nền tảng.

Thực hiện kiểu tiếp cận này, có thể loại bỏ không cần thiết nếu/elseif/else xây dựng với thời gian có thể đưa ra lỗi (nếu có 6 trong số mã này và thay đổi là cần thiết, bạn có thể quên cập nhật một trong số đó, hoặc bằng cách sao chép/dán, bạn có thể quên thay đổi lệnh để thực hiện)

+0

nó không phải là giải pháp –

+0

@KrzysztofCichocki bạn không giải thích tại sao bạn nghĩ nó không phải là giải pháp, theo cách đó, mọi người đọc câu trả lời này có thể đánh giá liệu có nên sử dụng Nó hay không. – OscarRyz

+0

Bạn không hiển thị bất kỳ mã nào thực sự hoạt động và mở trình duyệt mặc định cho java 1.5, chỉ một số bộ khung cho nó mà không có bất kỳ triển khai hữu ích nào, đó là lý do tại sao đây không phải là giải pháp. –

4

SWT mang đến cho bạn khả năng để lokk cho chương trình tiêu chuẩn để mở một tập tin thông qua:

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

đúng đây không phải là Cross-Platform từ SWT là nền tảng phụ thuộc, nhưng đối với tất cả các nền tảng mà bạn có thể sử dụng một bình thường SWT jar.

+0

Lưu ý: nguồn của Program.java ở đây http://kickjava.com/src/org/eclipse/swt/program/Program.java.htm. Có thể điều đó cũng có thể giúp ích cho quá nhiều – VonC

+0

Có lẽ điều này rất hữu ích đối với người dùng Java 1.5 + SWT. Nhưng việc sử dụng SWT chỉ cho điều này có thể không tối ưu. – asalamon74

0

Bạn có thể sử dụng cách mặc định của hệ điều hành để mở nó cho bạn.

  • Windows: "cmd/c fileName
  • Linux w/gnome "gnome-mở filename"
  • Linux w/Kde ??
  • OSX "mở filename"
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"); 
} 

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

Bạn cũng có thể, đa hình với điều đó. Bằng cách đó bạn có thể thêm tính linh hoạt để triển khai. Sau đó, bạn có thể tránh một chuỗi if/elseif/else cho hoạt động tiếp theo. – OscarRyz

+0

Bạn nên sử dụng 'xdg-open' thay vì' gnome-open' hoặc 'kfmclient' hoặc bất kỳ thứ gì, vì vậy nó hoạt động độc đáo hơn trong xfce hoặc các môi trường khác. –

12

JDIC là thư viện cung cấp chức năng giống như máy tính để bàn trong Java 1.5.

+1

Thư viện này dường như giải quyết được sự cố. Tôi không hiểu tại sao mọi người bỏ phiếu cho việc phát minh lại bánh xe ... –

-3

Chúng tôi đặt lệnh bên ngoài một nơi nào đó trong tệp cấu hình.

"JAR và mã nguồn" của bạn sẽ là "đa nền tảng", nhưng triển khai của bạn thì không.

Bạn cũng có thể làm điều gì đó như this answer. Bạn có thể đặt tên lớp của lớp nhà máy của triển khai "Deskop" vào tệp thiết lập. (có thể là hướng dẫn hoặc mùa xuân, nếu bạn thích)

5

Giống như bổ sung: Thay vì gnome-open, hãy sử dụng xdg-open. Nó là một phần của số XdgUtils, đây là một phần của gói hỗ trợ LSB Desktop (bắt đầu bằng 3.2).

Bạn có thể (nên) vẫn sử dụng gnome-open làm dự phòng, nhưng xdg-open cũng sẽ hoạt động trên máy tính để bàn không phải GNOME.

+0

Ngoài ra tuyệt vời. Tôi không biết gói này. – asalamon74

0

Câu trả lời khác (bằng boutta) đề xuất sử dụng SWT. Tôi sẽ không khuyên bạn nên tham khảo các thư viện để chỉ mục đích này, nhưng nếu bạn đang sử dụng nó đã có, chỉ cần thực hiện:

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

Hãy lưu ý rằng phương pháp này sẽ chỉ làm việc (và trở true) nếu một đối tượng Display có đã được tạo ra (ví dụ bằng cách tạo một Shell). Cũng lưu ý rằng nó phải chạy trong chủ đề chính; ví dụ:

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

Trong ví dụ trên, tôi đã khởi chạy URL, nhưng khởi chạy tệp hoạt động theo cùng một cách.

Các vấn đề liên quan