我有一个Java程序(带有一个swing gui),我想只有一个实例存在。如果它试图打开另一个程序实例,我希望将当前实例带到前台。
我该怎么做?
提前致谢。
答案 0 :(得分:4)
使用Java Web Start启动应用程序并实施SingleInstanceService
的JNLP API。这是demo. of the SingleInstanceService
。
如果它试图打开另一个程序实例,我希望将当前实例带到前台。
将其隐藏在SingleInstanceListener
的{{3}}方法中。它将传递为新发布提供的任何参数。现有实例决定如何处理新的args(例如,更改文件,添加新标签,忽略..)
答案 1 :(得分:3)
您可以使用ShutDownHook和锁定文件来执行此操作,请参阅此简单example。
我认为这是最简单的方式......
答案 2 :(得分:2)
Java中没有prev-instance,但您可以在temp(或/ var / run)目录中创建pid文件。 (并且在退出时让它File.deleteOnExit()
来清理它)
要将现有窗口置于顶部,您可以自行通知程序,通过命名管道,unix套接字或java远程方法调用等。简单&脏的方法是写一个小文件,比如$TEMP/foobar-app.bring-to-top
,程序应该定期轮询这个小文件,如果它存在,把窗口移到顶部并删除这个小文件。
我猜Java无法处理信号,即kill -HUP PID
可能不适用于Java应用程序。即使可能,也不是每个操作系统都有信号。
答案 3 :(得分:1)
我使用Socket和ServerSocket执行了一次:
首先,当您启动应用程序时,请在某个端口上进行ServerSocket侦听,例如4004
。诀窍是检查它是否抛出IOException
。如果是,则运行另一个应用程序或另一个应用程序使用该端口(check this list for commonly used ports;请注意,TCP和UDP端口不会相互阻塞),否则您可以继续应用程序启动。如果某个实例当前正在运行,您可能希望通过连接TCP Socket来通知它(这可以保证您的连接到达; UDP不会)。
以下是一个例子:
ServerSocket ss = null;
try {
ss = new ServerSocket(4004);
} catch (IOException ex0) {
// Port either occupied by your application or a foreign one
// -> Connect
Socket s = null;
try {
s = new Socket();
} catch (Exception ex1) {
// Something went wrong
}
if (s != null) {
// Send some singnal
}
}
if (ss == null) {
// Close or do something else
}
(我把这记录在我的记忆中,所以有些事情可能是错的或者可以做得更好)。
答案 4 :(得分:0)
在C#中,您通常会在Applicaiton启动时创建 Mutex 。如果您无法创建/获取它,则该应用程序的另一个实例已在运行。不幸的是,如果在Java中表现相同或者确切的语法是什么,我不能100%确定。
希望这有帮助。
答案 5 :(得分:-3)
模式单身:
class SingleInstance {
private static SingleInstance instance;
public SingleInstance getInstance() {
if (instance==null)
instance = new SingleInstance();
return instance;
}
private SingleInstance() {
//construct it!
}
}