我想知道是否有可能检查是否有用Java打开的对象(我的gui)的实例,如果可以,我将如何找到它?
答案 0 :(得分:1)
如果此问题适用于JFrame或JDialog,
等摇摆窗口,则可以使用以下代码 java.awt.Window win[] = java.awt.Window.getWindows();
for(int i=0;i<win.length;i++){
if (win[i].getName().equals("YourWindowName"))
isOpen = true;
break;
}
对于这个ypu需要给你的JFrame命名,如果它与打开的窗口匹配,它将设置为true并返回。
答案 1 :(得分:1)
我使用RMI来解决同样的问题。我的应用程序创建了Registry并在启动后将锁定对象放在那里。如果当时锁对象已经存在,那么它将通过RMI向现有应用程序发送消息并终止。发送的消息触发现有应用程序将其窗口移到顶部。这是代码
public static void main(String[] args) {
RmiManager rmiManager = new RmiManager();
rmiManager.createRmiRegistry();
if(rmiManager.isAlreadyRunning()) {
logger.error("Another application instance is running! Exit");
System.exit(0);
return;
}
rmiManager.registerApplication();
}
RmiManager.java实际上负责所有的东西
package myapp;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.io.File;
import java.io.IOException;
import java.rmi.registry.LocateRegistry;
import java.rmi.NotBoundException;
import java.rmi.registry.Registry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import org.apache.log4j.Logger;
public class RmiManager {
private static final String LOCK_OBJECT_NAME = "myapp";
private static final Logger logger = Logger.getLogger(RmiManager.class);
public void createRmiRegistry() {
try {
logger.debug("Creating RMI registry...");
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
logger.debug("RMI registry was created");
} catch (RemoteException e) {
logger.debug("RMI registry is already created");
}
}
public boolean isAlreadyRunning() {
try {
logger.debug("Checking if application is already running. Looking for RMI registry...");
Registry registry = LocateRegistry.getRegistry();
logger.debug("RMI registry obtained. Looking for RmiListener: " + LOCK_OBJECT_NAME + "...");
try {
IRmiListener rmiListener = (IRmiListener) registry.lookup(LOCK_OBJECT_NAME);
logger.debug("RmiListener got. Checking...");
boolean isAlreadyRunning = rmiListener.isAlreadyRunning();
logger.debug("IsAlreadyRunning result: " + isAlreadyRunning);
return isAlreadyRunning;
} catch (AccessException e) {
logger.error("Error accessing RMI registry!", e);
return false;
} catch (NotBoundException e) {
logger.debug("RMI listener wasn't found. There are no other application instances running");
return false;
}
} catch (RemoteException e) {
logger.error("RemoteException!", e);
return false;
}
}
public void registerApplication() {
try {
logger.debug("Registering application...");
RmiListenerImpl rmiListenerImpl = new RmiListenerImpl();
logger.debug("Exporting RmiListener object...");
IRmiListener rmiListener = (IRmiListener) UnicastRemoteObject.exportObject(rmiListenerImpl, Registry.REGISTRY_PORT);
logger.debug("RmiListener object was exported. Looking for RMI registry...");
Registry registry = LocateRegistry.getRegistry();
logger.debug("RMI registry found");
try {
logger.debug("Binding RmiListener to " + LOCK_OBJECT_NAME + "...");
registry.bind(LOCK_OBJECT_NAME, rmiListener);
logger.debug("RmiListener binding was done. Application registration complete.");
} catch (AccessException e) {
logger.error("AccessException!", e);
} catch (AlreadyBoundException e) {
logger.error("RmiListener object is already bind", e);
}
} catch (RemoteException e) {
logger.error("RemoteException!", e);
}
}
}
IRmiListener.java
package myapp;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IRmiListener extends Remote {
boolean isAlreadyRunning() throws RemoteException;
}
RmiListenerImpl.java
package myapp;
import java.rmi.RemoteException;
import org.apache.log4j.Logger;
public class RmiListenerImpl implements IRmiListener {
private static final Logger logger = Logger.getLogger( RmiListenerImpl.class );
@Override
public boolean isAlreadyRunning() throws RemoteException {
// here I notify my GUI class to pop up the window
return true;
}
}
我认为可以更简单。
答案 2 :(得分:0)
假设通过“打开UI对象”意味着Swing对话框和框架,最好以一种不需要一起查找打开实例的方式设计应用程序。
这可以通过提供一个工厂来实现,该工厂可以生成应用程序对话框和框架,而不是使用new JFrame
之类的东西。该工厂将在内部注册生成的实例,并将作为所有“打开UI对象”的单一参考点。
虽然在实现此类解决方案时要小心,因为每个注册对象都会有一个额外的引用,阻止GC按预期收集分配的内存。请使用弱引用(weak reference map)进行缓存。可以找到关于不同类型的Java引用的好博客文章here。
这样,如果您需要查找打开的UI对象,只需要求工厂提供打开的实例列表。