2008-11-28 16 views
11

Estoy usando Java 1.5 y me gustaría iniciar la aplicación asociada para abrir el archivo. Sé que Java 1.6 introdujo el Desktop API, pero necesito una solución para Java 1.5.Forma de plataforma cruzada para abrir un archivo usando Java 1.5

Hasta ahora he encontrado una manera de hacerlo en Windows:

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

¿Hay una manera de plataforma cruzada para hacerlo? O al menos una solución similar para Linux?

Respuesta

11

1 de this answer

Además me permito sugerir la siguiente implementación usando polimorfismo:

De esta manera usted puede agregar nueva plataforma más fácil mediante la reducción de acoplamiento entre las clases.

El código de cliente:

Desktop desktop = Desktop.getDesktop(); 

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

Los impl de Escritorio:

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

Este es sólo un ejemplo, en la vida real no vale para crear una nueva clase sólo para parametrizar un valor (la cadena de comandos% s) Pero imaginemos que cada método realiza otros pasos de una manera específica para la plataforma.

Al hacer este tipo de enfoque, puede eliminar las construcciones innecesarias if/elseif/else que con el tiempo pueden introducir errores (si hay 6 de ellos en el código y se necesita un cambio, puede olvidarse de actualizar uno de ellos, o al copiar/pegar puede olvidarse de cambiar el comando para ejecutar)

+0

no es una solución –

+0

@KrzysztofCichocki no explica por qué cree que no es una solución, de esa manera, las personas que leen esta respuesta pueden evaluar si se debe usar es o no – OscarRyz

+0

No mostró ningún código que realmente funcione y abre el navegador predeterminado para Java 1.5, solo un poco de esqueleto sin ninguna implementación útil, es por eso que esta no es una solución. –

4

SWT le da la posibilidad de lokk para el programa estándar para abrir un archivo a través de:

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

En sentido estricto no es compatible con varias plataformas desde SWT es dependiente de la plataforma, pero para cada plataforma se puede utilizar una diffenrent SWT jar.

+0

Nota: la fuente de Program.java está aquí http://kickjava.com/src/org/eclipse/swt/program/Program.java.htm. Puede ser que también pueda ayudar – VonC

+0

Probablemente esto sea muy útil para los usuarios de Java 1.5 + SWT. Pero usar SWT solo por esto podría no ser óptimo. – asalamon74

0

Puede usar la forma predeterminada del sistema operativo para abrirlo por usted.

  • de Windows: "cmd/c nomArchivo
  • Linux w/gnome "gnome-abierta nombre de fichero"
  • Linux w/Kde ??
  • OSx "abierta nombre de fichero"
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"); 
} 

y

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

También puede tomar polimorfismo con eso. De esta forma, puede agregar flexibilidad a la implementación. Entonces puede evitar otra cadena if/elseif/else para la siguiente operación. – OscarRyz

+0

Debe usar 'xdg-open' en lugar de' gnome-open' o 'kfmclient' o lo que sea, para que funcione mejor en xfce u otros entornos. –

12

JDIC es una biblioteca que proporciona funcionalidad de escritorio en Java 1.5.

+1

Esta biblioteca parece resolver el problema. No entiendo por qué la gente votó por reinventar la rueda ... –

-3

Nosotros ponemos el comando afuera en algún lugar del archivo de configuración.

Su "JAR y código fuente" serán "multiplataforma", pero su implementación no.

También puede hacer algo como this answer. Puede poner el nombre de clase de la clase de fábrica de la implementación "Deskop" en el archivo de instalación. (puede ser una guía o un resorte, si lo desea)

5

Solo como una adición: en lugar de gnome-open, use xdg-open. Es parte de XdgUtils, que a su vez son parte del paquete de soporte LSB Desktop (comenzando con 3.2).

Puede (debería) seguir usando gnome-open como alternativa, pero xdg-open también funcionará en escritorios que no sean de GNOME.

+0

Gran adición. No estaba al tanto de este paquete. – asalamon74

0

Otra respuesta (por boutta) sugiere el uso de SWT. No recomendaría hacer referencia a la biblioteca sólo para este propósito, pero si usted lo está utilizando ya, basta con ejecutar:

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

tomar en cuenta que este método sólo funciona (y volver true) si un objeto tiene ya Display creado (por ejemplo, creando un Shell). También tenga en cuenta que debe ejecutarse en el hilo principal; e.g .:

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

En el ejemplo anterior he lanzado una URL, pero el inicio de archivos funciona de la misma manera.

Cuestiones relacionadas