
|
auteur :
Ioan Calapodescu | Cette fonctionnalité n'est pas disponible dans l'API standard, car trop dépendante du système d'exploitation.
Plusieurs API (plus ou moins portables), utilisant JNI, existent pour pallier à ce manque :
|
lien : SysTray for Java
lien : Java System Tray Manager
|
|
auteur :
Ioan Calapodescu | La classe abstraite Preferences du package java.util.prefs permet d'enregistrer facilement certaines données. Les implémentations dépendent du système (registres, SGBD, fichiers, etc.), mais ceci est invisible pour l'utilisateur. Plusieurs niveaux de préférences peuvent être définis. Ceux-ci sont accessibles grâce aux méthodes statiques de la classe Preferences.
Niveaux de Preferences
- Preferences.systemRoot() : préférences globales du système.
- Preferences.systemNodeForPackage(Class c) : préférences du système pour une classe donnée.
- Preferences.userRoot() : préférences globales de l'utilisateur.
- Preferences.userNodeForPackage(Class c) : préférences globales de l'utilisateur pour une classe donnée.
Les Preferences associent à une clef (String) une valeur. On peut stocker dans les Preferences tout type primitif. Voici les méthodes correspondantes à :
La lecture de Preferences
Preferences prefs = Preferences.systemRoot();
String unString = prefs.get("uneClef","une valeur par défaut si il n'y a pas de valeur");
int unInt = prefs.getInt("clefInt",123);
L'écriture de Preferences
Preferences prefs = Preferences.systemRoot();
prefs.put("clef","valeur");
prefs.putInt("clefInt",456);
Pour un exemple plus complet, regardez le fichier ci-dessous. Il consiste en une fenêtre capable de "mémoriser" sa position, sa taille et son état (maximisée, iconifiée, etc.).
|
téléchargement : Exemple
|
|
auteurs :
duj, Ioan Calapodescu | De nombreux formats de fichiers textes peuvent être utilisés avec Java. Malheureusement, tous ne sont pas utilisables grâce à l'API standard. Voici quelques formats et les API qui peuvent les utiliser :
Format |
API |
Remarques |
HTML |
API Standard |
Cf. HTMLEditorKit, JEditorPane et JTextPane |
RTF |
API Standard |
Cf. RTFEditorKit, JEditorPane et JTextPane |
XML |
API Standard (SAX, DOM) |
Il existe de nombreuses librairies facilitant le travail avec ce type de documents |
PDF |
iText, FOP |
Ces deux librairies sont utilisées seulement pour la génération |
Excel |
POI, JExcelAPI |
|
Word |
POI |
|
|
|
auteur :
Johann Heymes | Cas de figure : Un composant donné a besoin d'informer un ou plusieurs composants externes que certains événements se sont produits.
Un petit exemple : Le composant MonBouton a besoin d'informer une liste d'objets que le bouton gauche de la souris est appuyé et que le bouton de la souris a été relaché.
Définir une nouvelle interface :
public interface MonBoutonMouseListener extends EventListener {
public void boutonGauchePresse (EventObject e);
public void boutonGaucheRelache (EventObject e);
}
/** import nécessaire : */
import javax.swing.event.EventListenerList;
/** attribut : */
protected EventListenerList listenerList;
/** instanciation nécessaire : (à faire dans son constructeur
* ou dans une méthode appelée par le constructeur)
*/
this.listenerList = new EventListenerList ();
/** méthode à faire :
* permet d'ajouter un composant dans la liste de ceux qui veulent
* être informés de l'évènement
*/
public void addMonBoutonMouseListener (MonBoutonMouseListener l) {
this.listenerList.add (MonBoutonMouseListener.class, l);
}
/** enlève un objet qui est actuellement écouteur de l'évènement */
public void removeMonBoutonMouseListener (MonBoutonMouseListener l) {
this.listenerList.remove (MonBoutonMouseListener.class, l);
}
/** lance un évènement à tous les objets écouteurs
* (== appelle la méthode boutonGauchePresse sur tous les objets
* écouteurs de la liste)
*/
protected void fireboutonGauchePresse () {
MonBoutonMouseListener [] listeners = (MonBoutonMouseListener [])
listenerList.getListeners( MonBoutonMouseListener.class);
EventObject e = new EventObject (this);
for (int i = listeners.length-1; i>=0; i--) {
listeners [i].boutonGauchePresse (e);
}
}
Il suffit ensuite d'appeler cette méthode à chaque fois que l'évènement approprié est généré.
|
téléchargement : Exemple d'implémentation.
|
|
auteur :
Clément Cunin | En Java les types de base sont passés aux méthodes par valeur, ils ne peuvent pas être modifiés. Il va falloir utiliser une instance de classe "encapsulant" un entier pour effectuer la modification. Attention la classe fournie Integer ne permet pas la modification et est donc inutile dans ce cas.
class MonEntier {
/** champ privé : */
private int value;
/** mise à jour de la valeur */
public void setValue(int newValue) {
value = newValue;
}
/** Acces à la valeur */
public int getValue() {
return( value);
}
}
Dans la méthode maMethode faire :
public void maMethode (MonEntier i) {
i.setValue(maNouvelleValeur);
}
|
|
auteur :
Johann Heymes | Contrôle-C, kill -9 et autres sont des méthodes permettant d'arrêter l'exécution du programme sans lui demander son avis. Pourtant, il est parfois nécessaire de faire au moins quelques instructions capitales telles que la fermeture de flux de fichier, d'une connexion réseaux ou une sauvegarde rapide. Pour se faire il est possible de définir un 'ShutdownHook' ce qui se traduit par un thread exécuté à la réception du signal de fin d'exécution.
Attention : Ce traitement final sera également éxécuté lors de l'arrêt normal de l'application.
|
téléchargement : Exemple d'implémentation.
|
|
auteur :
Clément Cunin | Le garbage Collector (rammasse miette) est la partie de la JVM qui s'occupe de la récupération des zones mémoires. Les phases de libération de la mémoire sont gérées de façon autonome, il est inutile de lui dire quand passer.
Il existe néanmoins la fonction gc de la classe java.lang.System qui permet de faire un appel explicite au garbage collector. Cet appel ne garantit pas que tous les objets inutiles seront supprimés de la mémoire.
System.gc ();
|
|
auteur :
Clément Cunin | Voici trois solutions :
public class MonEnum {
public final static int Val1=0;
public final static int Val2=1;
public final static int Val3=2;
}
On peut ensuite utiliser MonEnum.Val1, MonEnum.Val2 etc, ou mieux on peut faire une interface plutôt qu'une classe afin que les classes l'implémentant puissent directement appeler Val1, Val2...
Le problème reste le typage des éléments, rien n'empêche de passer un objet d'une énumération à la place d'une autre.
2ème solution : Cette deuxième catégorie de solutions, plus complexes, permet d'éviter ce problème. On peut par exemple penser à utiliser des instances de classes :
public final class MonEnum1 {
private MonEnum1() {
/** Rien à faire */
}
/** liste des valeurs */
public final static MonEnum1 Val1 = new MonEnum1();
public final static MonEnum1 Val2 = new MonEnum1();
public final static MonEnum1 Val3 = new MonEnum1();
}
Ainsi un éventuel objet de type MonEnum2 ne pourra jamais être utilisé à la place d'un objet de type Enum1 (Enum1.Val1 Enum1.Val2 ...).
2ème bis solution : La 2ème solution pose un autre problème, il reste possible d'utiliser la valeur 'null' alors que celle-ci n'appartient pas au domaine de notre énumération. Pour ce faire, rien de plus simple, si on considère val1 comme la valeur par défaut, on la déclare de la manière suivante :
public final static Enum1 val1 = null;
De cette manière il devient totalement impossible de passé un Enum1 non reconnu !
Conclusion : Les deux dernières méthodes posent toutefois un problème, le seule type d'argument accepté par un switch est l'entier. Il est donc impossible d'utiliser ces méthodes là où elle sont le plus souvent attendues. Il n'existe donc pas de solution miracle, à vous de choisir la solution qui correspond le mieux à vos contraintes.
|
lien : http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/enum/package-summary.html
|
|
auteur :
Clément Cunin | Si les paramètres passés au constructeur sont incohérents ou que la construction provoque une erreur, la création de l'objet est impossible et doit être annulée. Comme les méthodes, les constructeurs peuvent lever des exceptions, c'est la façon la plus simple d'annuler l'exécution du constructeur. Techniquement, l'objet est créer en mémoire (l'allocation de la mémoire a lieu au moment de l'appel du constructeur) mais l'appelant étant obligé de traiter l'exception, le pointeur vers cette objet est perdu et sera donc recupéré par le ramasse-miettes.
Une solution plus élégante consiste à utiliser par une méthode statique qui verifie les paramètres et ne fait l'appel au constructeur que si ceux-ci sont corrects.
public class Test {
/** Le constructeur est déclaré protected
* pour interdire son utilisation par les clients de la classe.
*/
protected Test(int val) {
}
public static Test createTest( int val ) {
if( val<100 ) {
return( new Test(val) );
} else {
return( null);
/** Ou alors on lève une exception... */
}
}
}
|
|
auteur :
bulbo | En utilisant la méthode:
Class c = Class.forName("com.developpez.MaClasse");
On utilise le ClassLoader du système. Ce ClassLoader cache l'information et ne rechargera pas la classe lors d'un nouvel appel a forName, et ce même si le fichier ".class" a changé depuis le dernier chargement.
Il y a deux solutions :
1 - La classe n'est pas présente dans le CLASSPATH
C'est le cas le plus simple, il suffit d'utiliser un nouveau URLClassLoader a chaque fois pour recharger une nouvelle version de la classe.
URL chemins[] = { new URL("file:/C:/MesClasses/") };
URLClassLoader loader = new URLClassLoader(chemins);
Class c = loader.loadClass("com.developpez.MaClasse");
Attention, il faut créer a chaque fois un nouvel URLClassLoader, sinon la classe est cachée par le loader.
Si la classe est présente dans le CLASSPATH c'est le ClassLoader du système qui la charge (et la met dans son cache).
2 - La classe est présente dans le CLASSPATH
Dans ce cas, on ne peut pas utiliser l'URLClassLoader. Il faut créer son propre ClassLoader qui hérite de la classe ClassLoader
import java.io.InputStream;
public class MonLoader extends ClassLoader
{
public Class loadNewClass(String aName) throws Exception
{
InputStream is = getClass().getResourceAsStream("/" + aName);
if (null == is)
{
return null;
}
byte buffer[] = new byte[is.available()];
is.read(buffer);
Class c = defineClass(aName, buffer, 0, buffer.length);
resolveClass(c);
return c;
}
}
Dans ce code, nous avons créé une nouvelle méthode "loadNewClass" qui recharge le fichier ".class" a chaque fois.
Le fait de ne pas avoir redéfini la méthode loadClass permet a ce nouveau ClassLoader d'utiliser le ClassLoader du système pour charger d'eventuelles classes mères ou interfaces.
Si la méthode loadClass est redéfinie il faut qu'elle puisse aussi trouver les super classes et interfaces des classes qui seront chargées, et ce sans recharger celles déjà présentes dans le système.
|
|
auteur :
xavlours | Un singleton est un objet qui ne peut être instancié qu'une seule et unique fois dans le programme.
Pour transformer une classe en singleton, il faut passer les constructeurs en accès private et ajouter au code une instance et un accesseur statiques :
public class Singleton {
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
private Singleton() {
}
}
Il existe une variante :
public class Singleton {
private static Singleton instance = null;
public static Singleton getInstance() {
if(instance == null)
instance = new Singleton();
return instance;
}
private Singleton() {
}
}
Enfin, pour accéder au singleton, il suffit d'appeler :
Singleton s = Singleton.getInstance();
|
lien : Le Singleton en environnement Multithread
|
|
auteur :
christopheJ | Le double-check locking est un idiome de programmation censé assurer la sécurité du Singleton en environnement multithread.
Attention, ce pattern ne marche pas !
Il peut etre écrit comme suit :
public static Singleton getInstance(){
if (instance==null)
{
synchronized (Singleton.class){
if(instance==null)
instance=new Singleton();
}
}
return instance;
}
|
|
auteur :
christopheJ | Il existe trois solutions pour sécuriser un Singleton dans un programme multithread :
- Synchroniser toute la méthode getInstance() et payer le coût de la synchronisation à chaque appel
- Utiliser ThreadLocal dont l'implémentation n'est pas plus performante que la synchronisation
- Abandonner la synchronisation et utiliser un initialiseur static quand la construction du Singleton ne nécessite pas de paramètres particuliers.
Pour plus d'informations : Le Singleton en environnement Multithread
|
Consultez les autres F.A.Q's
Les codes sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Pour le reste, ce document constitue une oeuvre intellectuelle protégée par les droits d'auteurs.
Ce document issu de http://www.developpez.com est soumis à deux licences, en fonction des contributeurs :
- Les contributions de Clément Cunin et Johann Heymes sont soumises aux termes de la la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies des contributions de Clément Cunin et Johann Heymes tant que cette note apparaît clairement :
"Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement".
- Pour ce qui est des autres contributions : Copyright © 2004 Developpez LLC : Tous droits réservés Developpez LLC. Aucune reproduction, ne peux en être faite sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
|
|
|