I\'m using Java 1.5 and I\'d like to launch the associated application to open the file. I know that Java 1.6 introduced the Desktop API, but I need a solution for J
+1 for this answer
Additionally I would suggest the following implementation using polymorphism:
This way you can add new platform easier by reducing coupling among classes.
The Client code:
Desktop desktop = Desktop.getDesktop();
desktop.open( aFile );
desktop.imaginaryAction( aFile );
The Desktop 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>
}
}
This is only an example, in real life is not worth to create a new class only to parametrize a value ( the command string %s ) But let's do imagine that each method performs another steps in platform specific way.
Doing this kind of approach, may remove unneeded if/elseif/else constructs that with time may introduce bugs ( if there are 6 of these in the code and a change is neede, you may forget to update one of them, or by copy/pasting you may forget to change the command to execute)
Another answer (by boutta) suggests using SWT. I wouldn't recommend referencing the library for this purpose only, but if you are using it already, simply execute:
Program.launch("http://google.com/");
Take note that this method will only work (and return true
) if a Display
object has already been created (for instance by creating a Shell
). Also take note that it must run in the main thread; e.g.:
Display.syncExec(new Runnable() {
public void run() {
Program.launch("http://google.com/");
}
});
In the example above I've launched a URL, but launching files works in the same way.
JDIC is a library that provides Desktop-like functionality in Java 1.5.
You can use the OS default way to open it for you.
SWT gives you the possibility to lokk for the standard program to open a file via:
final Program p = Program.findProgram(fileExtension);
p.execute(file.getAbsolutePath());
Strictly this isn't Cross-Platform since SWT is platform dependent, but for every platform you can use a diffenrent SWT jar.
Just as an addition: Rather than gnome-open
, use xdg-open
. It's part of the XdgUtils, which are in turn part of the LSB Desktop support package (starting with 3.2).
You can (should) still use gnome-open
as a fallback, but xdg-open
will also work on non-GNOME desktops.