PROGRAMMATION SWING ET XML

III. LA NOTION D'ACTION ET LES COMPOSANTS TEXTUELS.

4. Comment écrire un Document Listener

Un composant textuel Swing utilise un modèle, un objet Document pour stocker et éditer le texte. Les événements relatifs aux documents ont lieu lorsque se produit n'importe quel type de modifications sur le document. Il est bien sur possible d'enregistrer un document listener au document d'un composant textuel, plutot qu'au composant textuel en lui-meme.

L'applet suivante nous affiche les différents événements produit par le document sur les deux composants textuels :

Click this figure to run the applet.
Ceci est une image de l'applet, malheureusement comme elle utilise Swing, il est nécessaire
d'installer un PlugIn pour que cela fonctionne (éventuellement ;-). Tentez votre chance !

Sinon, vous pouvez toujours charger le code de l'applet DocumentEventDemo.java et la visualiser avec l'appletviewer. Voici comment se déroule la gestion des événements document :
 

public class DocumentEventDemo ... {
    ...// initialisations :
    textField = new JTextField(20);
    textField.addActionListener(new MyTextActionListener());
    textField.getDocument().addDocumentListener(new MyDocumentListener());
    textField.getDocument().putProperty("name", "Text Field");

    textArea = new JTextArea();
    textArea.getDocument().addDocumentListener(new MyDocumentListener());
    textArea.getDocument().putProperty("name", "Text Area");
    ...

class MyDocumentListener implements DocumentListener {
    String newline = "\n";

    public void insertUpdate(DocumentEvent e) {
        updateLog(e, "inserted into");
    }
    public void removeUpdate(DocumentEvent e) {
        updateLog(e, "removed from");
    }
    public void changedUpdate(DocumentEvent e) {
        //Plain text components don't fire these events
    }

    public void updateLog(DocumentEvent e, String action) {
        Document doc = (Document)e.getDocument();
        int changeLength = e.getLength();
        displayArea.append(
            changeLength + " character" +
            ((changeLength == 1) ? " " : "s ") +
            action + doc.getProperty("name") + "." + newline +
            "  Text length = " + doc.getLength() + newline);
    }
}

Les document listeners ne devraient pas modifier le contenu des documents qu'ils observent. En effet, la modification à déjà eu lieu lorsque les listeners sont notifiés des changements. Au lieu de cela, il faut écrire spécialisé un document qui surcharge les méthodes insertString et remove .

L'API Document Event

L'interface DocumentListener contient les trois méthodes suivantes :
 
void changedUpdate(DocumentEvent)
Cette méthode est appelée lorsqu'il y a un changement de style sur le texte. Ce type d'événement n'est produit que par les  StyledDocument -- un PlainDocument n'en produit pas (forcément ...).
void insertUpdate(DocumentEvent)
Cette méthode est invoquée lorsque du texte est inséré dans le document observé.
void removeUpdate(DocumentEvent)

Cette méthode est invoquée lorsque du texte est effacé du documeent observé.

Chaque événement de type document possède un seul paramètre : une instance de la classe implémentant l'interface DocumentEvent . Typiquement, l'objet passé dans cette méthode sera une instance de la classe DefaultDocumentEvent qui est définie dans AbstractDocument.

Pour récupérer la référence du document ayant émit l'événement, il faut utiliser la méthode getDocument de la classe DocumentEvent. Remarquez bien qu'en tant qu'interface,  DocumentEvent n'hérite pas de  EventObject. Ainsi, on n'a pas accés à la méthode getSource.

En plus de la méthode getDocument, l'interface DocumentEvent nécessite l'implémentation des méthodes suivantes :
 
 

int getLength()
Retourne la longueur du changement.
int getOffset()
Retourne la position dans le document ou le premier caractère a été changé.
ElementChange getChange(Element)
Retourne des informations concernant les éléments qui ont été modifiés dans le document, ainsi que la manière dont ils ont été modifiés. L'interface ElementChange est définie à l'intérieur de l'interface DocumentEvent.
EventType getType()

Retourne le type de modification ayant eu lieu. La classe EventType est définie dans l'interface DocumentEvent qui énumère tous les types de changements pouvant survenir sur un document : insertion de texte, effacement de texte, et modification du style du texte.