
FAQ Java GUIConsultez toutes les FAQ
Nombre d'auteurs : 51, nombre de questions : 152, dernière mise à jour : 21 décembre 2009
Sommaire→AWT et Swing→Composants textuels- Comment faire un JLabel de plusieurs lignes ?
- Comment faire un JTextArea avec un retour à la ligne automatique ?
- Comment permettre la saisie de mot de passe ? (texte saisi avec des étoiles)
- Comment contraindre la saisie dans un composant texte ?
- Comment utiliser un JFormattedTextField
- Comment avoir un éditeur de texte avec plusieurs styles de mise en page ?
- Comment rendre visible le dernier ajout de texte dans un JTextComponent ?
- Comment obtenir la liste des polices de caractères ?
- Comment aligner un texte dans un JSpinner ?
Le HTML :La plus simple des méthodes pour avoir un texte sur plusieurs lignes est d'utiliser l'interpréteur HTML du JLabel. Pour cela il faut que le texte soit entouré des balises '<html>' et '</html>'. Ensuite il faut remplacer les "\n" par des balises '<br>', et le tour est joué !
new JLabel("<html>ligne 1<br>ligne 2<br>etc...</html>");
Le composant texte :Il est également possible d'utiliser un javax.swing.JTextArea plus pratique à mettre en place que la version Html si le texte n'est pas fixé dans le code... Cette solution est néanmoins plus contraignante sur la mise en page et sur la gestion de l'apparence (par défaut le JTextArea n'a pas les mêmes couleurs qu'un JLabel).
(Un exemple est disponible en téléchargement)
JTextArea label = new JTextArea();
label.setText(text);
label.setEnabled(false);
La solution de la brute :Empiler 2 ou 3 JLabel les uns au dessus des autres devrait faire l'affaire :-).
A noter que la solution avec HTML marche également avec d'autres composants Swing tels que le JButton.
Téléchargement : Exemple de texte multi-ligne en utilisant un JTextArea.
Tout simplement en utilisant les méthodes setLineWrap(boolean) et setWrapStyleWord(boolean) de la classe javax.swing.JTextArea.
/** On souhaite un retour à ligne automatique : */
monTextArea.setLineWrap(true);
/** On souhaite que les mots ne soient pas coupés : */
monTextArea.setWrapStyleWord(true);
Awt
TextField txt = new TextField ();
txt.setEchoChar ('*');
Swing
JPasswordField txt = new JPasswordField ();
txt.setEchoChar ('*')
Exemple : Comment autoriser l'utilisateur à ne saisir que des entiers dans un champ texte. Trois solutions s'offrent à vous :
- écouter les évènements ;
- modifier le modèle du composant texte ;
- utiliser la classe javax.swing.JFormattedTextField (dispo seulement depuis le JDK 1.4).
Solution 1, les écouteurs (listener) :Il s'agit sûrement des premières solutions auxquelles on pense mais ce ne sont pas les plus simples à mettre en place ni les plus jolies. Je parle ici évidemment de java.awt.event.KeyListener ou javax.swing.event.DocumentListener et autres du même genre. Pour moi, ces solutions sont des solutions de rattrapage car techniquement elles permettent uniquement de nous informer d'un changement. Or si le changement est fait cela veux donc dire que le « mal » est déjà fait. Ce qui signifie que le composant texte à un moment donné est dans une situation non cohérente. Je m'arrêterai donc là sur ce sujet.
Solution 2, modification du modèle :La notion de modèle provient du design pattern MVC, Model-View-Controller Architecture, le but ici est donc de modifier directement ce que peut contenir un composant texte en ignorant tout le reste. Pour se faire il suffit de créer une classe qui dérive du modèle auquel le composant texte est associé. Pour information nous avons :
- JTextField et JTextArea : PlainDocument ;
- JEditorPane et JTextPane : DefaultStyledDocument.
Ces deux classes implémentent toutes deux l'interface javax.swing.text.Document qui définit entre autres la méthode insertString(int, java.lang.String, javax.swing.text.AttributeSet) et remove(int, int). Il suffit donc de créer une classe qui dérive de la classe modèle apropriée et de rédéfinir la ou les méthodes nécessaires. Notons que ces deux méthodes insertString et remove seront appelées automatiquement par les classes de Sun à chaque ajout ou suppression de chaîne. Notre redéfinition doit donc avoir pour but de valider ou non l'action. Par conséquent on notera que l'intégrité du composant texte n'est jamais bafouée (voir démo ci-dessous.)
Solution 3, la classe JFormattedTextField
Une toute nouvelle classe fait son apparition dans la version 1.4 du JDK. L'exemple ici est très réducteur de ses capacités mais la prise en main est peut-être moins évidente. En tout cas le résultat est là et il est même largement meilleur... regardez l'exemple :-)
A noter qu'on peut aussi utiliser un MaskFormatter à un JFormattedTextField. Pour cela, il vous suffit de créer un nouveau MaskFormatter avec le masque de votre choix puis d'installer ce mask sur votre JFormattedTextField via la méthode install de MaskFormatter. Cela permet encore plus de fonctionnalités à ce composant.
Lien : Model-View-Controller Architecture
Téléchargement : Exemple d'implémentation de la solution 2
Téléchargement : Exemple d'implémentation de la solution 3
JFormattedTextField et formats standards (depuis le JDK 1.4)
La classe JFormattedTextField possède un constructeur prenant en paramètre un Format. Cela permet de spécifer un format au champ de saisie.
Classes dérivées de Format :
- DateFormat
- MessageFormat
- NumberFormat
// champ de saisie depourcentages
JFormattedTextField champPourcentage = new JFormattedTextField(NumberFormat.getPercentInstance());
// champ de saisie de dates
JFormattedTextField champDate = new JFormattedTextField(DateFormat.getDateInstance()); // Dec 31, 2000
JFormattedTextField(DateFormat.getDateInstance(DateFormat.SHORT)); // 12/31/2000
JFormattedTextField et MaskFormatter (depuis le JDK 1.4)
Un MaskFormatter convient aux motifs à taille fixe (n° de téléphone, n° de sécurité social, n° de série...).
// pour un n° de téléphone en France
new MaskFormatter("## ## ## ## ##");
// pour un n° de sécurité social
new MaskFormatter("#-##-##-##-###-###-##");
Liste des symboles :
- # => Un chiffre
- ' => Un caractère d'échappement pour include un symbole dans le motif
- U => Une lettre (les minuscules sont changées en majuscules)
- L => Une lettre (les majuscules sont changées en minuscules)
- A => Un chiffre ou une lettre
- ? => Une lettre
- * => Tout caractère
- H => Tout caractère hexadécimal (0-9, a-f ou A-F)
On peut limiter les caractères valides en appelant l'une des méthodes suivantes : setValidCharacters(), setInvalidCharacters().
// Champ de saisie d'une case d'un échiquier (A1 à H8)
try
{
MaskFormatter mask = new MaskFormatter("U#");
mask.setValidCharacters("ABCDEFGH12345678");
JFormattedTextField noteField = new JFormattedTextField(mask);
}
catch (ParseException e)
{
}
Formatteurs personnalisés
Pour personnaliser un formatteur, il faut créer une classe dérivée de DefaultFormatter et redéfinir les méthodes
- String valueToString (Object value) throws ParseException
- Object StringToValue (String text) throws ParseException
La 1ere méthode transforme la valeur du champ en chaîne qui s'affiche.
La 2ème méthode analyse le texte tapé et le transforme en objet.
Quel composant choisir ?Vous avez le choix entre JTextPane et JEditorPane. En effet, ce sont les seuls à utiliser comme "Model" (Cf Model-View-Controller Architecture) un composant dérivant de AbstractDocument et implémentant l'interface StyledDocument.
Mise en page à la création :Si la mise en page est fixée lors de la création du document, il suffit de récupérer le Model du composant texte.
JTextPane monComposantTexte = new JTextPane ();
DefaultStyledDocument doc = (DefaultStyledDocument) monComposantTexte.getDocument ();
doc.insertString (offset, "texte à ajouter", /** [un style d'écriture] */);
Style déterminé a l'insertion :Si le style est connu lors de l'insertion, il faut créer une classe qui hérite de DefaultStyledDecument et redéfinir la méthode insertString(). Exemple pour écrire tout le texte avec le style nomme styleNormal sauf si l'on insert le mot 'HELP' :
/** Redéfini pour choisir l'effet de style à utiliser */
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
try {
/** si le texte inséré est égal à HELP le texte s'écrit
* avec le style "styleOp"
*/
if ( str.equals ("HELP") ) {
super.insertString (offs, str, getStyle ("styleOp"));
} else {
/** Sinon le texte est écrit avec le style "styleNormal" */
super.insertString (offs, str, getStyle ("styleNormal"));
}
} catch (BadLocationException e) {
System.out.println ("Tuuuttt erreur Insere");
}
}
(Voir l'exemple fourni.)
Modifier le Style après l'insertion :Pour cela il faut soit récupérer le Model du composant Texte, soit créer sa propre classe dérivant de DefaultStyledDocument.
JTextPane monComposantTexte = new JTextPane ();
DefaultStyledDocument doc = (DefaultStyledDocument) monComposantTexte.getDocument ();
doc.setCharacterAttributes (positionDeDepart, longueur, style, true);
Voir l'exemple fourni.)
Téléchargement : Editeur de texte simple, avec changement d'attribut d'une portion de texte
Deux solutions possibles :
On peut déplacer le "caret" :
monTextArea.setCaretPosition(monTextArea.getDocument().getLength ());
On demande au JTextComponent de transmettre à son parent les coordonnées d'un point qui doit être visible.
try {
int longueur = monTextArea.getDocument().getLength();
Rectangle rectangle = monTextArea.modelToView(longueur);
monTextArea.scrollRectToVisible(rectangle);
} catch (javax.swing.text.BadLocationException err) {
}
Téléchargement : MonJTextArea.java
Avant d'utiliser une police de caractères, il est fortement recommandé de vérifier qu'elle est présente sur le système. Les systèmes alternatifs disposent rarement des mêmes polices que Windows.
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
/** Liste de toutes les polices : */
Font[ ] polices = environment.getAllFonts();
/** Liste des noms de toutes les polices : */
String[ ] nomPolices = environment.getAvailableFontFamilyNames();
Lien : Comment dessiner en Java ?
Pour aligner un texte dans JSpinner il faut d'abord récupérer son textField. Ensuite de quoi, il faut modifier l'alignement de ce dernier. Voici un exemple avec tous les alignements possibles :
JSpinner spinner = new JSpinner();
JTextField textField = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
//Aligner texte à gauche
textField .setHorizontalAlignment(JTextField.LEFT);
//Aligner texte à droite (Par défault)
textField .setHorizontalAlignment(JTextField.RIGHT);
//Aligner le texte au centre
textField .setHorizontalAlignment(JTextField.CENTER);


















