检查打开的GUI实例

时间:2012-03-15 12:38:21

标签: java user-interface object

我想知道是否有可能检查是否有用Java打开的对象(我的gui)的实例,如果可以,我将如何找到它?

3 个答案:

答案 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对象,只需要求工厂提供打开的实例列表。