2010-05-30 12 views
1

J'utilise un port ServerSocket pour exécuter une seule instance de mon application Java Swing, donc si un utilisateur essaye d'ouvrir une autre instance du programme, je lui montre un avertissement "Une autre instance est déjà ouverte". Cela fonctionne très bien, mais au lieu de montrer ce message, je veux mettre l'accent sur l'application en cours d'exécution, comme le font certains programmes (MSN Messenger), même si elle a été minimisée.Comment faire pour mettre au point l'application en cours d'exécution?

Existe-t-il une solution pour cela pour différents systèmes d'exploitation?

Répondre

2

Étant donné que vous utilisez une socket serveur, je suppose que vous utilisez java.net.BindException pour détecter que votre application est déjà en cours d'exécution. Si vous démarrez une seconde instance, vous pouvez envoyer un message de contrôle qui vous demande de normaliser la première application (si elle est minimisée) avant de quitter.

if (msg == BRING_TO_FRONT) { 
    frame.setState(Frame.NORMAL); 
    frame.toFront(); 
} 
+0

Je utilise BindException mais comment obtenir l'instance "frame"? – Brad

+0

Je pense que l'idée ici est d'ouvrir un client socket à partir de la deuxième instance de l'application, connectez-le au serveur socket de la première instance d'application, et utilisez cette connexion pour dire à la première application de se mettre en avant. – jfpoilpret

+0

Exactement 2ème application établit une connexion à la première application et envoie un message. La 1ère application connaît déjà son cadre et peut exécuter l'extrait fourni dans ma réponse. Vous ne pouvez pas énumérer les fenêtres de manière portable. – stacker

1

Je ne sais pas si cela est tout à fait raison, mais voici le code final je l'ai utilisé et il fonctionne très bien pour moi:

public class Loader { 
private static final int PORT = 9999; 
private static ServerSocket serverSocket = null; // Server 
private static Socket socket = null; // CLient 
private static final String focusProgram = "FOCUS"; 

public static void main(String[] args) { 
    if(!isProgramRunning()) { 
     Main main = new Main(); 
     main.setVisible(true); 
    } 
    else { 
     System.exit(2); 
    } 
} 

private static boolean isProgramRunning() { 
    try { 
     serverSocket = new ServerSocket(PORT,0,InetAddress.getByAddress(new byte[] {127,0,0,1})); // Bind to localhost adapter with a zero connection queue. 
     SwingWorker<String, Void> anotherThread = new SwingWorker<String, Void>() { // Do some code in another normal thread. 
      @Override 
      public String doInBackground() { // This method is to execute a long code in the other thread in background. 
       serverSocketListener(); 
       return ""; 
      } 
     }; 
     anotherThread.execute(); // Execute the other tread. 
    } 
    catch (BindException e) { 
     System.err.println("Already running."); 
     clientSocketListener(); 

     return true; 
    } 
    catch (IOException e) { 
     System.err.println("Unexpected error."); 
     e.printStackTrace(); 

     return true; 
    } 

    return false; 
} 

public static void serverSocketListener() { // Server socket 
    try { 
     System.out.println("Listener socket opened to prevent any other program instance."); 
     socket = serverSocket.accept(); 
     BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

     if(in.readLine().equals(focusProgram)) { // Restore the opened instance however you want. 
      Global.getCurrentFrame().setState(Frame.NORMAL); 
      Global.getCurrentFrame().toFront(); 
     }  
    } catch (IOException e) { 
     e.printStackTrace(); 
     System.exit(-1); 
    } 
} 

public static void clientSocketListener() { // Client socket 
    try{ 
     socket = new Socket(InetAddress.getByAddress(new byte[] {127,0,0,1}), PORT); 
     PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
     out.println(focusProgram); 
    } catch (IOException e) { 
     System.out.println("No I/O"); 
     System.exit(1); 
    } 
} 

}