2012-03-15 5 views
0

オブジェクトのインスタンス(私のgui)がJavaで開いているかどうかを確認することが可能かどうか疑問に思っていました。開いているGUIインスタンスを確認する

+0

はい、可能です。いいえ、使用しているグラフィックスライブラリなどのことを知らないと、どのように言わないのでしょうか。 – Thomas

+0

同じプロセス内か外部かを見つけることはできますか? – AlexR

+0

同じプロセス内から – Biscuit128

答えて

1

この質問は、JFrameのかJDialogのようなスイングウィンドウのためであるあなたのJFrameに名前を与えるために、このypu必要性については

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; 
    } 

、それが開いているウィンドウと一致した場合、それがtrueに設定されます場合は、次のコードを使用することができますし、戻る。

+0

他のJVMによって作成されたウィンドウインスタンスは識別されません。 –

+0

いいえ、それはとにかく同じプロセスです –

+0

OPの最後のコメントを読んでください* "ただ一つのインスタンスのユーザーインターフェースが必要です" *。ユーザが別のインスタンスを起動させると、独自のJVMを持ち、それ自身の 'Window'インスタンスの配列を持ちます。 –

0

「開いているUIオブジェクト」とは、スイングのダイアログとフレームを意味すると仮定して、開いているインスタンスを一括して探す必要性を排除するようにアプリケーションを設計する方がよいでしょう。

これは、new JFrameのようなものを使用する代わりに、アプリケーションのダイアログとフレームを生成するファクトリを提供することで実現できます。このファクトリは、生成されたインスタンスを内部的に登録し、すべての「開いているUIオブジェクト」の単一の参照ポイントとして機能します。

登録されたオブジェクトごとに、GCが割り当てられたメモリを意図したとおりに収集することを妨げる追加の参照が1つあるため、このようなソリューションを実装する場合は注意が必要です。キャッシングに弱い参照(weak reference map)を使用してください。異なる種類のJavaリファレンスに関する良いブログ記事はhereです。

オープンなUIオブジェクトを見つける必要がある場合は、開いているインスタンスのリストを提供するように工場にリクエストするだけです。

1

同じ問題を解決するためにRMIを使用しました。私のアプリケーションはレジストリを作成し、開始後にそこにロックオブジェクトを配置します。その時点でロックオブジェクトがすでに存在する場合、RMIを介して既存のアプリケーションにメッセージを送信し、終了します。送信されたメッセージは、既存のアプリケーションを起動してそのウィンドウを上に移動させます。ここでは、実際にすべてのもの

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); 
     } 
    } 
} 

する責任があるコード

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 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; 
    } 
} 

それはありますよりシンプルにすることができます おもう。

関連する問題