2012-03-15 23 views
0

我想知道是否有可能檢查是否有在Java中打開的對象(我的gui)的實例,如果有的話我怎麼能找到它?檢查打開的GUI實例

+0

是的,這是可能的。不,我們不能告訴你如果不知道你正在使用哪個圖形庫等等。 – Thomas 2012-03-15 12:42:22

+0

你的意思是在相同的過程中還是從外部找到它? – AlexR 2012-03-15 12:42:46

+0

來自同一進程 – Biscuit128 2012-03-15 12:43:48

回答

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,如果與打開的窗口相匹配,將設置真,返回。

+0

這不會識別由其他JVM創建的窗口實例。 – 2012-03-15 14:00:50

+0

不,但它是相同的過程無論如何 – 2012-03-15 14:01:21

+0

閱讀OP的最後評論*「我只是想單個實例用戶界面」*。如果用戶啓動另一個實例,它將擁有自己的JVM,並擁有自己的'Window'實例數組。 – 2012-03-15 14:04:05

0

假設通過「開放式UI對象」來表示Swing對話框和框架,最好是設計應用程序的方式不需要一起查找打開的實例。

這可以通過提供一個工廠來生成應用程序對話框和框架而不是使用像new JFrame這樣的工具來實現。該工廠將在內部註冊生成的實例,並將作爲所有「打開的UI對象」的單一參考點。

儘管在實施這樣的解決方案時要小心,因爲每個註冊對象都有一個額外的引用,防止GC按預期收集分配的內存。請使用弱引用(weak reference map)進行緩存。有關不同類型Java參考的好博客文章可以在here找到。

這種方式如果你需要找到一個開放的UI對象,只需要你的工廠提供一個打開的實例列表。

1

我用RMI來解決同樣的問題。我的應用程序創建註冊表並在啓動後將鎖對象放置在那裏。如果此時鎖對象已經存在,則它通過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; 
    } 
} 

它可以更簡單 我認爲。