我有一个Java程序(带有swing gui(,我希望只有一个实例存在。如果它试图打开程序的另一个实例,我希望将当前实例置于前台。
我该怎么做?
提前谢谢。
使用 Java Web Start 启动应用程序并实现 JNLP API 的SingleInstanceService
。 这是一个演示。的SingleInstanceService
.
在如果它试图打开程序的另一个实例,我希望将当前实例置于前台。
SingleInstanceListener
的新激活(字符串[](方法中挂接它。 它将传递为新发布提供的任何参数。 现有实例可以决定如何处理新的参数(例如更改文件,添加新选项卡,忽略......
您可以使用 ShutDownHook 和锁定文件来完成,请参阅这个简单示例。
我认为这是最简单的方法...
Java 中没有 prev-instance,但您可以在 temp(或/var/run(目录中创建一个 pid 文件。(并使其File.deleteOnExit()
在退出时清洁它(
要将现有窗口置于顶部,您可以通过命名管道、unix 套接字或 java 远程方法调用等方式自行通知程序。一种简单而肮脏的方法是写入一个小文件,比如$TEMP/foobar-app.bring-to-top
,程序应该定期轮询这个小文件,如果它存在,将窗口带到顶部并删除这个小文件。
我猜Java无法处理信号,即kill -HUP PID
可能不适用于Java应用程序。即使可以,也不是每个操作系统都有信号。
我曾经用一个套接字和一个ServerSocket做过这个:
首先,当您启动应用程序时,让 ServerSocket 侦听某个端口,例如 4004
。诀窍是检查它是否抛出IOException
。如果是,则有另一个应用程序正在运行,或者该端口被另一个应用程序使用(查看此列表以了解常用端口;请注意,TCP 和 UDP 端口不会相互阻塞(,否则您可以继续启动应用程序。如果实例当前正在运行,您可能希望通过连接 TCP 套接字来通知它(这保证您的连接到达;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
}
(我是根据我的记忆写的,所以有些事情可能是错的,或者可以做得更好(。
在 C# 中,通常在 Applicaiton 启动时创建互斥体。如果无法创建/获取它,则应用程序的另一个实例已在运行。不幸的是,我不能 100% 确定这在 Java 中的行为是否相同或确切的语法是什么。
希望这有帮助。
模式单调:
class SingleInstance {
private static SingleInstance instance;
public SingleInstance getInstance() {
if (instance==null)
instance = new SingleInstance();
return instance;
}
private SingleInstance() {
//construct it!
}
}