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 Java 1.5.
我正在使用Java 1.5,我想启动相关的应用程序来打开文件。我知道Java 1.6引入了桌面API,但我需要Java 1.5的解决方案。
So far I found a way to do it in Windows:
到目前为止,我找到了一种在Windows下操作的方法:
Runtime.getRuntime().exec(new String[]{ "rundll32",
"url.dll,FileProtocolHandler", fileName });
Is there a cross-platform way to do it? Or at least a similar solution for Linux?
有跨平台的方法吗?或者至少有一个类似的Linux解决方案?
8 个解决方案
#1
11
+1 for this answer
+ 1这个答案
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:
桌面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.
这只是一个例子,在现实生活中不值得创建一个新类,只需要参数化一个值(命令字符串%s),但是让我们想象一下,每个方法都以特定于平台的方式执行另一个步骤。
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)
做这样的方法,可以消除不必要的如果elseif /其他结构随着时间的推移可能会引入bug(如果有6种neede代码和改变,你可能忘了更新其中一个,或复制/粘贴您可能忘记更改命令执行)
#2
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));
}
#3
12
JDIC is a library that provides Desktop-like functionality in Java 1.5.
JDIC是一个在Java 1.5中提供类似桌面功能的库。
#4
5
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).
作为补充:不要使用gnome-open,使用xdgc -open。它是XdgUtils的一部分,它是LSB桌面支持包的一部分(从3.2开始)。
You can (should) still use gnome-open
as a fallback, but xdg-open
will also work on non-GNOME desktops.
您仍然可以(应该)使用gnome-open作为后备,但是xdgg -open也可以用于非gnome桌面。
#5
4
SWT gives you the possibility to lokk for the standard program to open a file via:
SWT为标准程序提供了lokk通过以下方式打开文件的可能性:
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.
严格来说,这并不是跨平台的,因为SWT依赖于平台,但是对于每个平台,您都可以使用一个困难的SWT jar。
#6
0
You can use the OS default way to open it for you.
您可以使用OS默认方式为您打开它。
- Windows: "cmd /c fileName
- 窗户:“cmd / c文件名
- Linux w/gnome "gnome-open filename"
- Linux w / gnome“gnome-open文件名”
- Linux w/Kde ??
- Linux w / Kde ? ?
- OSx "open filename"
- OSx“开放文件名”
#7
0
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:
另一个答案(布塔)建议使用SWT。我不建议仅为这个目的引用库,但是如果您已经使用它,只需执行:
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.:
注意,如果已经创建了一个显示对象(例如通过创建Shell),那么这个方法将只工作(并返回true)。还要注意,它必须在主线程中运行;例如:
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.
在上面的示例中,我已经启动了一个URL,但是启动文件的工作方式是相同的。
#8
-3
We do put the command outside somewhere in the configuration file.
我们确实将命令放在配置文件的某个地方。
Your "JAR and source code" will be "cross-platform", but your deployment doesn't.
您的“JAR和源代码”将是“跨平台的”,但是您的部署没有。
You can also do something like this answer. You can put the classname of the factory class of the "Deskop" implementation into the setup file. (may be guide or spring, if you like)
你也可以这样做。您可以将“Deskop”实现的工厂类的类名放入安装文件中。(可以是导游,也可以是春天)
#1
11
+1 for this answer
+ 1这个答案
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:
桌面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.
这只是一个例子,在现实生活中不值得创建一个新类,只需要参数化一个值(命令字符串%s),但是让我们想象一下,每个方法都以特定于平台的方式执行另一个步骤。
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)
做这样的方法,可以消除不必要的如果elseif /其他结构随着时间的推移可能会引入bug(如果有6种neede代码和改变,你可能忘了更新其中一个,或复制/粘贴您可能忘记更改命令执行)
#2
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));
}
#3
12
JDIC is a library that provides Desktop-like functionality in Java 1.5.
JDIC是一个在Java 1.5中提供类似桌面功能的库。
#4
5
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).
作为补充:不要使用gnome-open,使用xdgc -open。它是XdgUtils的一部分,它是LSB桌面支持包的一部分(从3.2开始)。
You can (should) still use gnome-open
as a fallback, but xdg-open
will also work on non-GNOME desktops.
您仍然可以(应该)使用gnome-open作为后备,但是xdgg -open也可以用于非gnome桌面。
#5
4
SWT gives you the possibility to lokk for the standard program to open a file via:
SWT为标准程序提供了lokk通过以下方式打开文件的可能性:
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.
严格来说,这并不是跨平台的,因为SWT依赖于平台,但是对于每个平台,您都可以使用一个困难的SWT jar。
#6
0
You can use the OS default way to open it for you.
您可以使用OS默认方式为您打开它。
- Windows: "cmd /c fileName
- 窗户:“cmd / c文件名
- Linux w/gnome "gnome-open filename"
- Linux w / gnome“gnome-open文件名”
- Linux w/Kde ??
- Linux w / Kde ? ?
- OSx "open filename"
- OSx“开放文件名”
#7
0
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:
另一个答案(布塔)建议使用SWT。我不建议仅为这个目的引用库,但是如果您已经使用它,只需执行:
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.:
注意,如果已经创建了一个显示对象(例如通过创建Shell),那么这个方法将只工作(并返回true)。还要注意,它必须在主线程中运行;例如:
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.
在上面的示例中,我已经启动了一个URL,但是启动文件的工作方式是相同的。
#8
-3
We do put the command outside somewhere in the configuration file.
我们确实将命令放在配置文件的某个地方。
Your "JAR and source code" will be "cross-platform", but your deployment doesn't.
您的“JAR和源代码”将是“跨平台的”,但是您的部署没有。
You can also do something like this answer. You can put the classname of the factory class of the "Deskop" implementation into the setup file. (may be guide or spring, if you like)
你也可以这样做。您可以将“Deskop”实现的工厂类的类名放入安装文件中。(可以是导游,也可以是春天)