|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
INSTANCE UNIQUE D'UNE APPLICATION
Information sur la source
Description
La demande revenant souvent sur les forums (et ayant cherché moi-même par le passé), j'ai développé une classe permettant de gérer le fait qu'une application ne doit être lancée qu'une seule fois. Son utilisation est très simple, il suffit de construire un objet UniqueInstance, en passant en paramètre le port de communication à utiliser, le message à communiquer si une application est déjà lancée, et les actions à effectuer lorsqu'une nouvelle instance a essayé d'être lancée (typiquement, passer l'application courante en premier-plan).
Source
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.Scanner;
- import java.util.logging.Logger;
-
- /**
- * Cette classe permet d'assurer l'unicité de l'instance de l'application. Deux applications ne peuvent pas être lancées
- * simultanément. Voici un exemple typique d'utilisation :
- *
- * <pre>
- * // Port à utiliser pour communiquer avec l'instance de l'application lancée.
- * final int PORT = 32145;
- * // Message à envoyer à l'application lancée lorsqu'une autre instance essaye de démarrer.
- * final String MESSAGE = "nomDeMonApplication";
- * // Actions à effectuer lorsqu'une autre instance essaye de démarrer.
- * final Runnable RUN_ON_RECEIVE = new Runnable() {
- * public void run() {
- * if(mainFrame != null) {
- * // Si la fenêtre n'est pas visible (uniquement dans le systray par exemple), on la rend visible.
- * if(!mainFrame.isVisible())
- * mainFrame.setVisible(true);
- * // On demande à la mettre au premier plan.
- * mainFrame.toFront();
- * }
- * }
- * });
- *
- * UniqueInstance uniqueInstance = new UniqueInstance(PORT, MESSAGE, RUN_ON_RECEIVE);
- * // Si aucune autre instance n'est lancée...
- * if(uniqueInstance.launch()) {
- * // On démarre l'application.
- * new MonApplication();
- * }
- * </pre>
- *
- * @author rom1v
- */
- public class UniqueInstance {
-
- /** Port d'écoute utilisé pour l'unique instance de l'application. */
- private int port;
-
- /** Message à envoyer à l'éventuelle application déjà lancée. */
- private String message;
-
- /** Actions à effectuer lorsqu'une autre instance de l'application a indiqué qu'elle avait essayé de démarrer. */
- private Runnable runOnReceive;
-
- /**
- * Créer un gestionnaire d'instance unique de l'application.
- *
- * @param port
- * Port d'écoute utilisé pour l'unique instance de l'application.
- * @param message
- * Message à envoyer à l'éventuelle application déjà lancée, {@code null} si aucune action.
- * @param runOnReceive
- * Actions à effectuer lorsqu'une autre instance de l'application a indiqué qu'elle avait essayé de
- * démarrer, {@code null} pour aucune action.
- */
- public UniqueInstance(int port, String message, Runnable runOnReceive) {
- assert port > 0 && port < 1 << 16 : "Le port doit être entre 1 et 65535";
- assert message != null || runOnReceive == null : "Il y a des actions à effectuer => le message ne doit pas être null.";
- this.port = port;
- this.message = message;
- this.runOnReceive = runOnReceive;
- }
-
- /**
- * Créer un gestionnaire d'instance unique de l'application. Ce constructeur désactive la communication entre
- * l'instance déjà lancée et l'instance qui essaye de démarrer.
- *
- * @param port
- * Port d'écoute utilisé pour l'unique instance de l'application.
- */
- public UniqueInstance(int port) {
- this(port, null, null);
- }
-
- /**
- * Essaye de démarrer le gestionnaire d'instance unique. Si l'initialisation a réussi, c'est que l'instance est
- * unique. Sinon, c'est qu'une autre instance de l'application est déjà lancée. L'appel de cette méthode prévient
- * l'application déjà lancée qu'une autre vient d'essayer de se connecter.
- *
- * @return {@code true} si l'instance de l'application est unique.
- */
- public boolean launch() {
- /* Indique si l'instance du programme est unique. */
- boolean unique;
-
- try {
- /* On crée une socket sur le port défini. */
- final ServerSocket server = new ServerSocket(port);
-
- /* Si la création de la socket réussit, c'est que l'instance du programme est unique, aucune autre n'existe. */
- unique = true;
-
- /* Si il y a des actions à faire lorsqu'une autre instance essaye de démarrer... */
- if(runOnReceive != null) {
-
- /* On lance un Thread d'écoute sur ce port. */
- Thread portListenerThread = new Thread() {
-
- @Override public void run() {
- /* Tant que l'application est lancée... */
- while(true) {
- try {
- /* On attend qu'une socket se connecte sur le serveur. */
- final Socket socket = server.accept();
-
- /* Si une socket est connectée, on écoute le message envoyé dans un nouveau Thread. */
- new Thread() {
-
- @Override public void run() {
- receive(socket);
- }
- }.start();
- } catch(IOException e) {
- Logger.getLogger("UniqueInstance").warning("Attente de connexion de socket échouée.");
- }
- }
- }
- };
-
- /* Le Thread d'écoute de port est démon. */
- portListenerThread.setDaemon(true);
-
- /* On démarre le Thread. */
- portListenerThread.start();
- }
- } catch(IOException e) {
- /* Si la création de la socket échoue, c'est que l'instance de n'est pas unique, une autre n'existe. */
- unique = false;
-
- /* Si des actions sont prévues par l'instance déjà lancée... */
- if(runOnReceive != null) {
- /*
- * Dans ce cas, on envoie un message à l'autre instance de l'application pour lui demander d'avoir le
- * focus (par exemple).
- */
- send();
- }
- }
- return unique;
- }
-
- /**
- * Envoie un message à l'instance de l'application déjà ouverte.
- */
- private void send() {
- PrintWriter pw = null;
- try {
- /* On se connecte sur la machine locale. */
- Socket socket = new Socket("localhost", port);
-
- /* On définit un PrintWriter pour écrire sur la sortie de la socket. */
- pw = new PrintWriter(socket.getOutputStream());
-
- /* On écrit le message sur la socket. */
- pw.write(message);
- } catch(IOException e) {
- Logger.getLogger("UniqueInstance").warning("Écriture sur flux de sortie de la socket échoué.");
- } finally {
- if(pw != null)
- pw.close();
- }
- }
-
- /**
- * Reçoit un message d'une socket s'étant connectée au serveur d'écoute. Si ce message est le message de l'instance
- * unique, l'application demande le focus.
- *
- * @param socket
- * Socket connecté au serveur d'écoute.
- */
- private void receive(Socket socket) {
- Scanner sc = null;
-
- try {
- /* On n'écoute que 5 secondes, si aucun message n'est reçu, tant pis... */
- socket.setSoTimeout(5000);
-
- /* On définit un Scanner pour lire sur l'entrée de la socket. */
- sc = new Scanner(socket.getInputStream());
-
- /* On ne lit qu'une ligne. */
- String s = sc.nextLine();
-
- /* Si cette ligne est le message de l'instance unique... */
- if(message.equals(s)) {
- /* On exécute le code demandé. */
- runOnReceive.run();
- }
- } catch(IOException e) {
- Logger.getLogger("UniqueInstance").warning("Lecture du flux d'entrée de la socket échoué.");
- } finally {
- if(sc != null)
- sc.close();
- }
-
- }
-
- }
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Logger;
/**
* Cette classe permet d'assurer l'unicité de l'instance de l'application. Deux applications ne peuvent pas être lancées
* simultanément. Voici un exemple typique d'utilisation :
*
* <pre>
* // Port à utiliser pour communiquer avec l'instance de l'application lancée.
* final int PORT = 32145;
* // Message à envoyer à l'application lancée lorsqu'une autre instance essaye de démarrer.
* final String MESSAGE = "nomDeMonApplication";
* // Actions à effectuer lorsqu'une autre instance essaye de démarrer.
* final Runnable RUN_ON_RECEIVE = new Runnable() {
* public void run() {
* if(mainFrame != null) {
* // Si la fenêtre n'est pas visible (uniquement dans le systray par exemple), on la rend visible.
* if(!mainFrame.isVisible())
* mainFrame.setVisible(true);
* // On demande à la mettre au premier plan.
* mainFrame.toFront();
* }
* }
* });
*
* UniqueInstance uniqueInstance = new UniqueInstance(PORT, MESSAGE, RUN_ON_RECEIVE);
* // Si aucune autre instance n'est lancée...
* if(uniqueInstance.launch()) {
* // On démarre l'application.
* new MonApplication();
* }
* </pre>
*
* @author rom1v
*/
public class UniqueInstance {
/** Port d'écoute utilisé pour l'unique instance de l'application. */
private int port;
/** Message à envoyer à l'éventuelle application déjà lancée. */
private String message;
/** Actions à effectuer lorsqu'une autre instance de l'application a indiqué qu'elle avait essayé de démarrer. */
private Runnable runOnReceive;
/**
* Créer un gestionnaire d'instance unique de l'application.
*
* @param port
* Port d'écoute utilisé pour l'unique instance de l'application.
* @param message
* Message à envoyer à l'éventuelle application déjà lancée, {@code null} si aucune action.
* @param runOnReceive
* Actions à effectuer lorsqu'une autre instance de l'application a indiqué qu'elle avait essayé de
* démarrer, {@code null} pour aucune action.
*/
public UniqueInstance(int port, String message, Runnable runOnReceive) {
assert port > 0 && port < 1 << 16 : "Le port doit être entre 1 et 65535";
assert message != null || runOnReceive == null : "Il y a des actions à effectuer => le message ne doit pas être null.";
this.port = port;
this.message = message;
this.runOnReceive = runOnReceive;
}
/**
* Créer un gestionnaire d'instance unique de l'application. Ce constructeur désactive la communication entre
* l'instance déjà lancée et l'instance qui essaye de démarrer.
*
* @param port
* Port d'écoute utilisé pour l'unique instance de l'application.
*/
public UniqueInstance(int port) {
this(port, null, null);
}
/**
* Essaye de démarrer le gestionnaire d'instance unique. Si l'initialisation a réussi, c'est que l'instance est
* unique. Sinon, c'est qu'une autre instance de l'application est déjà lancée. L'appel de cette méthode prévient
* l'application déjà lancée qu'une autre vient d'essayer de se connecter.
*
* @return {@code true} si l'instance de l'application est unique.
*/
public boolean launch() {
/* Indique si l'instance du programme est unique. */
boolean unique;
try {
/* On crée une socket sur le port défini. */
final ServerSocket server = new ServerSocket(port);
/* Si la création de la socket réussit, c'est que l'instance du programme est unique, aucune autre n'existe. */
unique = true;
/* Si il y a des actions à faire lorsqu'une autre instance essaye de démarrer... */
if(runOnReceive != null) {
/* On lance un Thread d'écoute sur ce port. */
Thread portListenerThread = new Thread() {
@Override public void run() {
/* Tant que l'application est lancée... */
while(true) {
try {
/* On attend qu'une socket se connecte sur le serveur. */
final Socket socket = server.accept();
/* Si une socket est connectée, on écoute le message envoyé dans un nouveau Thread. */
new Thread() {
@Override public void run() {
receive(socket);
}
}.start();
} catch(IOException e) {
Logger.getLogger("UniqueInstance").warning("Attente de connexion de socket échouée.");
}
}
}
};
/* Le Thread d'écoute de port est démon. */
portListenerThread.setDaemon(true);
/* On démarre le Thread. */
portListenerThread.start();
}
} catch(IOException e) {
/* Si la création de la socket échoue, c'est que l'instance de n'est pas unique, une autre n'existe. */
unique = false;
/* Si des actions sont prévues par l'instance déjà lancée... */
if(runOnReceive != null) {
/*
* Dans ce cas, on envoie un message à l'autre instance de l'application pour lui demander d'avoir le
* focus (par exemple).
*/
send();
}
}
return unique;
}
/**
* Envoie un message à l'instance de l'application déjà ouverte.
*/
private void send() {
PrintWriter pw = null;
try {
/* On se connecte sur la machine locale. */
Socket socket = new Socket("localhost", port);
/* On définit un PrintWriter pour écrire sur la sortie de la socket. */
pw = new PrintWriter(socket.getOutputStream());
/* On écrit le message sur la socket. */
pw.write(message);
} catch(IOException e) {
Logger.getLogger("UniqueInstance").warning("Écriture sur flux de sortie de la socket échoué.");
} finally {
if(pw != null)
pw.close();
}
}
/**
* Reçoit un message d'une socket s'étant connectée au serveur d'écoute. Si ce message est le message de l'instance
* unique, l'application demande le focus.
*
* @param socket
* Socket connecté au serveur d'écoute.
*/
private void receive(Socket socket) {
Scanner sc = null;
try {
/* On n'écoute que 5 secondes, si aucun message n'est reçu, tant pis... */
socket.setSoTimeout(5000);
/* On définit un Scanner pour lire sur l'entrée de la socket. */
sc = new Scanner(socket.getInputStream());
/* On ne lit qu'une ligne. */
String s = sc.nextLine();
/* Si cette ligne est le message de l'instance unique... */
if(message.equals(s)) {
/* On exécute le code demandé. */
runOnReceive.run();
}
} catch(IOException e) {
Logger.getLogger("UniqueInstance").warning("Lecture du flux d'entrée de la socket échoué.");
} finally {
if(sc != null)
sc.close();
}
}
}
Conclusion
Exemple d'utilisation... // Port à utiliser pour communiquer avec l'instance de l'application lancée. final int PORT = 32145; // Message à envoyer à l'application lancée lorsqu'une autre instance essaye de démarrer. final String MESSAGE = "nomDeMonApplication"; // Actions à effectuer lorsqu'une autre instance essaye de démarrer. final Runnable RUN_ON_RECEIVE = new Runnable() { public void run() { if(mainFrame != null) { // Si la fenêtre n'est pas visible (uniquement dans le systray par exemple), on la rend visible. if(!mainFrame.isVisible()) mainFrame.setVisible(true); // On demande à la mettre au premier plan. mainFrame.toFront(); } } }); UniqueInstance uniqueInstance = new UniqueInstance(PORT, MESSAGE, RUN_ON_RECEIVE); // Si aucune autre instance n'est lancée... if(uniqueInstance.launch()) { // On démarre l'application. new MonApplication(); }
Historique
- 28 octobre 2006 14:37:48 :
- problèmes d'espacements dans le code source copié
Sources du même auteur
Sources de la même categorie
Sources en rapport avec celle ci
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Unique instance de programme [ par indiana_jules ]
Salut, j'aimerais pouvoir n'avoir qu'une seule instance de mon programme qui tourne. Existe-t-il un moyen propre de le faire ? (sans passer par un Ser
java et une application windows [ par benmor ]
Bonjours à tous,Donc voila mon probleme, j'ai fait une petite application java afin de procèder a des actions répétitives.Cette ap
transformation d'une application java en une applet [ par steflanul ]
bonsoir!! je suis désolé mais je n'arrive toujours pas à transformer mon application en une applet! il me dit toujours apllet non initi
Tester une application J2EE [ par lnp ]
Salut tout le monde,On m'a dit qu'il existe des applications qui testent les applications J2EE...Est-ce que quelqu'un peut me dire où trouver ce
comment configueur un serveur smtp pour une application java (mail) [ par zazou1 ]
salut a tous,vous pouvez m'aidez pour configueur un serveur smtp sur windows XP (pour une application java (e_mail)).merci d'avance.
Deploiment application erreur [ par mael974 ]
Bonjour a tous.g trjs un ti souci lors du deploiement de mon appli (sous tomcat) !! Voici la structure (tres simple) : ds le web_apps jai mon reper
chat/FTP sécurisé [ par kabaouhanen ]
pour réaliser une application chat/FTP sécurisée(cryptographie) quelle est le language le plus convenable pour cette application. Merci
application web I THINK [ par khaledirb7 ]
Je doit développer une applicationen adoptant une architecture trois tiers , je veut utiliser jbuilder comme outil de développementet o
ajax et servlet [ par bf83 ]
bonjour tout le monde,je fais une application avec les servlets et je veux utiliser la notion d'ajax cda l'objet xmlhttprequest .je sais les utilsier
[J2ME] Compilation OK ==> nokia pas OK [ par JuJu ]
Bonjour, j'ai un problème avec une application J2ME. L'application marche à la perfection sur emulateur Wireless toolkit mais est inutilisab
|
Téléchargements
Logiciels à télécharger sur le même thème :
|