Les variables d’environnement sont des chaînes des texte donnant des informations utiles à l’exécution d’un programme Java.
Il faut faire attention car certaines variables d’environnement ne sont pas portables: par exemple les systèmes Applet/Mac n’ont pas de varibales d’environnement, et les systèmes DOS (Windows) utilisent un système de variables d’environnement différent de celui utilisé sur les systèmes UNIX.
Nous allons distinguer dans cet article 3 types de variables différents: celles que l’on peut spécifier à l’exécution d’un programme Java, en ajoutant des options à la commende "java maClasse" (portables sur tous les systèmes d’exploitation); celles que l’on peut définir avant l’exécution d’un programme, une bonne fois pour toutes, comme le célébrissime CLASSPATH (ce sont ces variables d’enviromment qui posent problème selon l’OS sous lequel est exécuté notre application Java); et, pour finir, les variables système, définies par la spécification Java, non modifiables, qui renseignent sur la JVM utilisée, et qui sont indépendantes de l’OS sous lequel tourne notre programme.
Lors du travail avec les Properties, java.util.Properties, on utilise un fichier de propriétés. On peut par exemple créer 3 fichiers de propriétés qui renfermeront les valeurs en chaînes dures des textes d’une interface graphique.
On aura donc par exemple:
# Premier fichier: pour une enterface en français
# Ce fichier s’appelle francais.properties
monBouton1 = "OK"
monBouton2 = "Annuler"
# Second fichier: pour la même application, avec l’interface traduite en anglais
# Ce fichier s’appelle anglais.properties
monBouton1 = "OK"
monBouton2 = "Cancel"
# Troisième fichier: pour la même application, avec l’interface traduite en martien (langue des petits hommes verts)
# Ce fichier s’appelle martien.properties
monBouton1 = "GlupGlup"
monBouton2 = "Gniorf"
On a ainsi 3 fichiers qui contiennent le label de tous les éléments de notre interface graphique. On va lancer notre programme en lui indiquant que l’on veut utiliser l’un ou l’autre des fichiers… selon si notre utilisateur est français, américian, ou martien !
java -Dlangue=martien.properties MaClasse
On utilise une variable que l’on appelle "langue" dans laquelle sera stockée le nom du fichier de propriétés à charger.
Il ne nous reste plus qu’à charger ce fichier dans notre programme Java.
String env = System.getProperty("langue");
Alors, quelle langue parlera notre application ? Vous dites le martien ? C’est ça !
Notre variable "langue" contient le nom du fichier de propriétés à charger, nous allons donc le charger:
Properties envVars = new Properties();
envVars.load(env);
NOTE: on a travaillé avec les propriétés, ce qui a un peu compliqué les choses, mais c’était pour donner un exemple pratique, on aurait aussi bien pu, par exemple, indiquer une image à charger:
java -Dimage=monLogo.gif MaClasse
ImageIcon img = new ImageIcon(System.getProperty("image"));
Il est très important dans tous les cas de ne pas laisser d’espace entre le -D et le nom de la variable et des deu côtés du =.
Si vous avec compris le premier type, vous avec compris le second, car c’est une variation du premier…
On définit une variable, par exemple:
# Sous DOS (Windows), on ajoute cette ligne à l’autoexec.bat
MON_CHEMIN_PERSO="C:\Mes Documents\Mes Images\"
# Sous UNIX
export MON_CHEMIN_PERSO=/home/moi/mes_images/:$MON_CHEMIN_PERSO
Et au lancement de notre programme Java, on écrira:
# Windows
java MaClasse %MON_CHEMIN_PERSO%
# UNIX
java MaClasse $MON_CHEMIN_PESO
La procédure pour récupérer la variable dans le programme, on la lit dans la méthode main() comme argument[0].
Personnellement je n’aime pas cette methode, mais elle existe…
Comme expliqué plus haut, le troisième type est totalement différent: vous ne pouvez pas modifier les variables d’environnement ce de type, elles sont internes au langage Java et servent à fournir des informations sur la JVM hôte.
La syntaxe pour récupérer ce genre de propriétés est la suivante:
String propriete = java.lang.System.getProperty(String prop);
Exemple:
final String USER_HOME = System.getProperty("user.home");
Voici un tableau des différentes propriétés auxquelles l’on peut avoir accès:
Sur fond bleu clair les plus utilisées.
Valeur |
Signification |
java.version |
Version du JRE |
java.vendor |
"Vendor" du JRE |
java.vendor.url |
URL du "Vendor" |
java.vm.specification.version |
JVM version de specification |
java.vm.specification.vendor |
JVM "vendor" de specification |
java.vm.specification.name |
JVM nom de specification |
java.vm.version |
JVM version d'implémentation |
java.vm.vendor |
JVM "vendor" d'implémentation |
java.vm.name |
JVM nom d'implémentation |
java.home |
Répertoire de java.exe |
java.specification.version |
JRE version de specification |
java.specification.vendor |
JRE "vendor" de specification |
java.specification.name |
JRE nom de specification |
java.class.version |
Numéro de version de Java |
java.class.path |
Le CLASSPATH |
java.ext.dirs |
Répertoire des extensions |
os.name |
Nom du système d'exploitation |
os.arch |
Nom de l'architechture de l'OS |
os.version |
Numéro de version de l'OS |
file.separator |
Sérarateur de fichiers (1) |
line.separator |
Séparateur de lignes (2) |
path.separator |
Séparateur de chemins (3) |
user.name |
Nom du compte utilisateur |
user.home |
Répertoire par défaut de l'utilisateur |
user.dir |
Répertoire où se trouve la classe principale |
(1) "/" sous UNIX "\" sous Windows</p> (2) (3) Tutoriel distribué pour le FAQ Java de Java-France www.java-france.com / www.jgflsoft.com |
Le multimédia est devenu un problème majeur dans le développement de logiciels. En effet, un programme doté d’une belle interface, avec des boutons animés, qui font du bruits en réponse aux actions de l’utilisateur, etc…, est devenu un atout pour séduire le gran public. Même si votre logiciel est très puissant, le meilleur dans son domaine, beaucoup (toujours trop) d’utilisateurs lui préfèreront un concurrent si tant est que celui-ci soit plus beau et plus convivial. L’interface graphique n’est donc pas à négliger, loin de là !
Je vous propose donc un petit tutoriel expliquant comment jouer des sons dans un programme Java. Ce tutoriel est cependant particulier: il concerne Java 1.1 en plus ancien, mais il est intéressant tout de même ! Je m’explique: il n’était pas possible à l’époque de jouer un son autre part que dans des applets sans utiliser de classes non documentées et très peu connues. Ce sont ces classes bien pratiques qui sont utilisées ici.
Vous pouvez utiliser cette technique dans vos programmes Java 2 (SDK 1.2, 1.3 & 1.4) si vous ne voulez par avoir recours aux nouvelles techniques.
Les classes non documentées font partie du paquetage sun.audio .
On notera cependant une forte restriction: n’essayez pas de jouer un fichier de 3 GO contentenant l’integrale de la 9ème symphonie de Beethoven, en qualité CD… cela ne fonctionnera pas avec cette méthode. Le format utilisé en Java par défaut est le format AU, plutôt destiné à faire un "ping", "plouf", ou "plaf" lorsque l’utilisateur clique sur un bouton qu’à jouer un morceau de classique…
Passons donc au code commenté:
Ecrit par Narcanes pour l’association Java-France/Jgflsoft
www.java-france.com / www.jgflsoft.com
Réédité pour Valhalla GFBLOG.
Montpellier, 18 octobre 2001.
Il n’existe pas par défaut en Java de méthode permettant de récupérer une série de nombres venant de l’utilisateur, comme le fait la méthode scanf() en C/C++. Il faut donc ruser, et écrire quelques lignes de code pour arriver à nos fins.
Pour récupérer un argument (chaîne, nombre, …) au cours de l’exécution d’un programme en ligne de commande, il faut utiliser le méthode readline() de la classe DataInputStream. Cette méthode renvoie une chaîne, nous devons ensuite convertir cette chaîne en nombre. Pour cela on utilisera les String Tokenizers.
Ce que vous devez faire: récupérer avec DataInputStream.readline() la chaîne de nombres.
L’utilisateur aura à saisir par exemple "23 32 5 47 22.3 55.221" pour avoir les entiers 23, puis 32, puis 5, puis 47, et les flottants 22.3 et 55.221.
Notre code sépare les différents nombres contenus dans la chaîne:
String s = "23 32 5 47 22.3 55.221";
java.util.StringTokenizer st = new java.util.StringTokenizer(s);
while (st.hasMoreTokens())
{ System.out.println("Le nombre suivant est: " + st.nextToken() + "\n");
}
Voici ce qui sort:
23
32
5
47
22.3
55.221
Pour convertir les chaînes sorties en nombres, on peut utiliser différentes méthodes, dont celle expliquée dans un autre article de cette FAQ (Convertir des String en int, float… et vice-versa).
Voici le code non commenté:
Note: depuis Java 1.1, pour avoir un Short et/ou un Byte on passera par Integer (comme pour avoir un int) mais en utilisant soit Integer.byteValue() soit Integer.shortValue().
Ecrit par Narcanes pour l’association Java-France/Jgflsoft
www.java-france.com / www.jgflsoft.com
Réédité pour Valhalla GFBLOG.
Montpellier, 18 octobre 2001.
Vous pouvez remplacer "TextArea" par "composant
texte" dans le titre de ce tutoriel, car le code ci-dessous fonctionne
avec tous les composants texte: TextArea, JTextArea, JTextPane, JEditorPane.
(Avec TextArea le titre est plus parlant)
Le but de cet article est de montrer comment récupérer
le contenu d’un composant texte pour l’enregistrer dans un fichier, avec ou
sans JFileChooser pour choisir le nom du fichier de sortie.
Le code d’enregistrement est extrèmement simple:
// A insérer dans un bloc try...catch
try
{ FileWriter lu = new FileWriter(monFichier);
// Créer un objet java.io.FileWriter avec comme argument le mon du
fichier dans lequel enregsitrer
BufferedWriter out = new BufferedWriter(lu);
// Mettre le flux en tampon (en cache)
out.write(textArea.getText()); //
Balancer dans le flux le contenu de la zone de texte
out.close(); // Fermer le flux (c'est
toujours mieux de le fermer explicitement)
} catch (IOException er) {;}
On suppose que l’on a:
- un String du nom de "monFichier" indiquant le nom du fichier dans
lequel enregistrer le texte
ex: String monFichier = "monFichier.txt";
- Un composant de texte du nom de textArea
ex: JTextArea textArea = new JTextArea();
Le code est complet et fonctionel ! On peut l’insérer
dans une méthode ou directement dans un gestionnaire d’évènements
!
Mais une fonction souvent nécessaire supplémentaire
est d’ajouter un JFileChooser en amont pour que l’utilisateur puisse spécifier
lui même le nom du fichier, sans que nous ayons à le lui imposer,
comme ici…
Voici donc la procédure:
try
{ JFileChooser filechoose = new JFileChooser();
// Créer un JFileChooser
filechoose.setCurrentDirectory(new
File(".")); // Le répertoire
source du JFileChooser est le répertoire d'où est lancé
notre programme
String approve = new String("ENREGISTRER");
// Le bouton pour valider l'enregistrement portera la
mention ENREGSITRER
int resultatEnregistrer = filechoose.showDialog(filechoose,
approve); // Pour afficher le JFileChooser...
if (resultatEnregistrer ==
JFileChooser.APPROVE_OPTION) // Si l'utilisateur clique
sur le bouton ENREGSITRER
{ String monFichier= new String(filechoose.getSelectedFile().toString());
// Récupérer le nom du fichier qu'il a spécifié
if(monFichier.endsWith(".txt")
|| monFichier.endsWith(".TXT")) {;}
// Si ce nom de fichier finit par .txt ou .TXT, ne rien faire et passer à
a suite
else (monFichier = monFichier+ ".txt");
// Sinon renommer le fichier pour qu'il porte l'extension .txt
{ // INSERER
ICI LE CODE EXPLIQUE CI-DESSUS POUR ENREGISTRER LE FICHIER
}
}
} catch (IOException er) {;}
Et voilà, on a un beau petit JFileChooser
qui nous demande de taper le nom du fichier que l'on veut enregsitrer !
</p>
Vous pouvez remplacer "TextArea" par "composant
texte" dans le titre de ce tutoriel, car le code ci-dessous fonctionne
avec tous les composants texte: TextArea, JTextArea, JTextPane, JEditorPane.
(Avec TextArea le titre est plus parlant)
Ce tutoriel explique comment ouvrir le contenu d’un fichier
dans un JTextArea, avec ou sans JFileChooser.
Le code d’ouverture est très simple:
try
{ FileInputStream fis = new FileInputStream(monFichier);
// Créer un flux d'entrée avec comme paramètre le nom
du fichier à ouvrir
int n;
while ((n = fis.available())
> 0) // tant qu'il y a des données dans le flux...
{ byte[] b = new
byte[n]; // récupérer
le byte à l'endroit n et le stocker dans un tableau de bytes
int result
= fis.read(b); // lire ce tableau de byte à l'endroit
désiré
if (result
== -1) break; // si le
byte est -1, c'est que le flux est arrivé à sa fin (par définition)
String s = new String(b);
// assembler les bytes pour former une chaîne
textArea.setText(s); //
insérer cette chaîne dans notre composant de texte
}
} catch (Exception err) {;}
Ceci suppose que l’on a créé
- un String du nom de nonFichier pointant vers le fichier à ouvrir.
String monFichier = "C:\Mes Documents\le_beau_ficher.txt";
- un composant de texte dans lequel afficher le texte:
JTextArea textArea = new JTextArea();
Le code est complet et fonctionel ! On peut l’insérer
dans une méthode ou directement dans un gestionnaire d’évènements
!
Mais une fonction souvent nécessaire supplémentaire
est d’ajouter un JFileChooser en amont pour que l’utilisateur puisse spécifier
lui même le nom du fichier, sans que nous ayons à le lui imposer,
comme ici…
Voici donc la procédure:
try
{ JFileChooser filechoose = new JFileChooser();
// Créer un JFileChooser
filechoose.setCurrentDirectory(new File("."));
// Le répertoire source
du JFileChooser est le répertoire d'où est lancé notre
programme
String approve = new String("OUVRIR");
// Le bouton pour valider l'enregistrement
portera la mention OUVRIR
String monFichier= null; //
On ne sait pas pour l'instant quel sera le fichier à ouvrir
int resultatOuvrir = filechoose.showDialog(filechoose,
approve); // Pour afficher
le JFileChooser...
if(resultatOuvrir == filechoose.APPROVE_OPTION)
// Si l'utilisateur clique
sur le bouton OUVRIR
{ monFichier =
filechoose.getSelectedFile().toString();
// Récupérer
le nom du fichier qu'il a spécifié
// INSERER ICI LE CODE EXPLIQUE CI-DESSUS
POUR OUVRIR LE FICHIER
}
}catch (IOException er) {;}
Et voilà, on a un beau petit JFileChooser
qui nous demande de sélectionner le fichier à ouvrir !
Tutoriel distribué pour le FAQ Java de Java-France www.java-france.com
/ www.jgflsoft.com
Réédité pour Valhalla GFBLOG.
Ecrit à Montpellier le 30 septembre 2001
Parmi les nombreuses fonctionnalités des versions Pro et Entreprise de JBuilder 5, on peut trouver un outil ("Wizard") très utile, qui permet de "ressources les Strings" de vos programmes.
Un exemple est le bienvenu pour montrer l’ampleur d’une telle fonction: vous créez votre programme avec une interface en français, et, par exemple, une fenêtre (classe héritant de JFrame) avec pour titre "Bienvenue dans mon logiciel !", par l’instruction this.setTitle("Bienvenue dans mon logiciel !");. Si vous décidez de traduire votre logiciel dans plusieurs autres langues, vous devrez ré-écrire votre code en remplaçant à chaque fois votre phrase par sa traductions dans les langues désirées. Vous allez donc devoir créer X versions de votre code source et les compiler… c’est long et contraignant.
Le créer des "Strings ressourcés" permet de remédier à ce problème. En effet, la procédure change du tout au tout: tous les messages sont créés dans un fichier texte brut que l’on peut éditer sous n’importe quel bloc-notes. Pour distribuer des versions dans des langues étrangères, il suffira donc de créer plusieurs versions de ce fichier texte ! Le code lui même n’est pas changé.
Note: on utilise ici la version US de JBuilder… la procédure est similaire dans la version française.
Voici donc la procédure en images:
1) Une fois votre classe implémentée, lancer l’assistant dans JBuilder, c’est la dernière entrée du menu "Wizard": "Resource Strings"
2) Une fenêtre s’ouvre, on est invité à spécifier le nom du "ResourceBundle", en général Res est le nom par défaut.
On doit ensuite spécifier que l’on veut créer des ressources à partir des chaînes dures de notre classe, en cochant le premier Radio. On clique ensuite sur Next (Suivant).
3) Une fenêtre s’ouvre avec toutes les chaînes dures de votre classe, on peut choisir de décocher les chaînes que l’on ne veut pas voir exporter (j’ai décoché ici n’importe quoi sans faire attention de qui il s’agissait).
Tout est coché par défaut.
L’ instruction dans laquelle se trouve le String sélectionné est affichée en bas de la fenêtre. Ici le String vide (qui correspond à 1 espace de la barre d’espace) se trouve dans l’appel de la méthode updateTitle(""); (et on voit bien qu’elle admet ici comme argument une chaîne vide).
NOTE: dans la suite de cet article je n’ai pas gardé les mêmes chaînes que celles que vous pouvez voir sur cette capture d’écran, en effet, il n’est d’aucun intérêt de ressources les chaînes affichées ci-contre. J’utilise dans la suite de ce tutoriel un exemple concret, sur une URL, ce qui est vraiment plus utile: pas besoin de recompiler le programme à chaque changement d’adresse du site !!
On clique ensuite sur Finish (Terminer).
4) L’opération est terminée.
Nous allons maintenant nous intéresser à ce qu’a fait JBuilder.
On voit pour commencer qu’il a créé un objet statique ResourceBundle nommé "res" et qui est créé avec pour argument la chaîne "Res" qui en en fait le nom du fichier texte brut dans lequel sont stockées les chaînes.
5) En parcourant le code de notre classe, on s’aperçoit que certaines instructions ont été changées. Ici, l’instruction était:
jTextPane1.setPage("http://perso.wanadoo.fr/guillaume/cadre_droit.htm");
qui a été modifiée en ce qu’on voit sur la capture d’écran.
On conclue que notre URL ci-dessus correspond à l’entrée "ACTU_ADDRESS" dans le fichier texte brut sur lequel pointe notre objet REsourceBundle "res".
6) Nous allons donc voir ce fichier texte brut pour savoir comment il est formé. On peut le trouver dans la liste des fichiers du projet, en haut à gauche de la fenêtre de JBuilder.
On l’ouvre en double-cliquant dessus.
7) Et voilà notre fichier.
La première ligne est un commentaire (syntaxe des commentaires Unix: ligne débutant par dièse #). Les autres lignes sont simplement les correspondances des chaînes que nous avions dans nos classes. On peut voir la chaîne représentée par l’entrée ACTU_ADDRESS, chaîne que j’ai citée plus haut. On note aussi la syntaxe un peu particulière: "http://" au lieu de"http://". Ceci s’explique par le fait que les deux points (:) sont un caractère spécial et que l’anti-slash () sert à signaler la présence d’un caractère spécial. N’y faites pas attention, mais respectez la syntaxe si vous changez votre URL. Je tiens à dire, pour terminer, que cet exemple est fonctionnel, puis qu’il s’agit du fichier de ressources qu’utilise ML. (regardez dans le JAR de ML…).
Conclusion:
Pour reprendre notre premier exemple, on oppose:
Sans les Strings ressourcés (3 compilations) | Avec les Strings ressourcés (1 compilation) |
this.setTitle("Bienvenue dans mon logiciel</p>
!"); | this.setTitle(res.getString("BONJOUR")); | </tr>
Dans le fichier de propriétés: |
Ceci ne concerne pas vraiment une technique de programmation, c’est plutôt un exercice pour se former l’esprit, et c’est aussi la démonstration que Java peut servir pour le calcul mathématique.
L’algo mis en place est le plus simple dans le genre: on premd un nombre impair, on le divise par chaque entier impair entre 3 et sa racine carrée. S’il n’a aucun diviseur il est premier.
// Le nombre candidat de départ, mettez la valeur que vous désirez, ce sera le nombre de départ et le programme ira en choisissant des nombres de plus en plus grands
long candidat = 1000;
while (true) // ou for (;;) sont des boucles infinies qui ne vérifient pas de condition
{
// on invoque la méthode estPremier() qui renvoie un booleen: oui ou non le nombre qu’on lui soumet est premier, l’instruction if(estPremier(candidate)) est équivalente
// à if (estPremier(candidate) == true)
if(estPremier(candidate)) {System.out.println(">Est premier le nombre: " + candidate);
}
private static boolean estPremier(long candidat)
{
// Diviser le nombre par tous les entiers impairs entre 3 et sa racine
double racine = Math.sqrt(candidate);
for (long i = 3; i <= sqrt; i += 2) // on incrémente de 2 pour sauter les pairs
{
// si le modulo, c-à-d le reste de la division euclidienne est 0, le nombre est divisible par i, i est donc un facteur, le nombre n’est pas premier.
if (candidat % i == 0) return false;
}
// Si la cdt ci-dessus n’est jamais vérifiée, alors le nombre est premier:
return true;
}
Et voilà, vous n’avez plus qu’à rédiger la méthode main() où à incorporer ce code dans une de vos classes, ici les premiers sont sortis en console. (System.out)
Tutoriel distribué pour le FAQ Java de www.jgflsoft.com ou www.java-france.com
Réédité pour Valhalla GFBLOG.
Ecrit à Montpellier le 31 août 2001
Cet article de la FAQ Java de l’association Java-France a pour but d’expliquer la procédure à suivre pour afficher des pages HTML, qui répondent aux liens, dans un JEditorPane ou un JTextPane (même procédure). En effet, ces deux composnats (JTextPane héritant de JEditorPane) implémentent des méthodes compliquées (plusieurs milliers de lignes de code) permettant de formater un document au format HTML, et de lancer une connexion pour afficher une nouvelle page si l’on clique sur un lien.
Nous allons donc voir, en 3 points, comment faire pour mettre en place un tel JEditorPane.
1) Le déclarer, l’insérer dans l’interface (dans un JScrollPane de préférence), et faire tout ce qu’il faut pour qu’il s’affiche dans ue fenêtre quand on lance le programme.
2) L’interdire en écriture: editorPane.setEditable(false);
3) Créer un gestionnaire d’évènements "HyperlinkListener".
editorPane.addHyperlinkListener(new HyperlinkListener()
{ public void hyperlinkUpdate(HyperlinkEvent event)
{ if (event.geteventType() == HyperlinkEvent.EventType.ACTIVATED)
{ try
{editorPane.setPage(event.getURL());
}catch(IOException ioe) {;}
}
}
}
});
Et voilà le travail !
Tutoriel distribué pour le FAQ Java de www.jgflsoft.com ou www.java-france.com
Réédité pour Valhalla GFBLOG.
Ecrit à Montpellier le 31 août 2001