Swing : MouseClickEvent sur un textArea

Fermé
arscy Messages postés 173 Date d'inscription dimanche 26 janvier 2014 Statut Membre Dernière intervention 5 octobre 2023 - 1 mai 2023 à 15:05
arscy Messages postés 173 Date d'inscription dimanche 26 janvier 2014 Statut Membre Dernière intervention 5 octobre 2023 - 1 mai 2023 à 17:23

Bonjour,

Je suis en train d'expérimenter un peu d'IHM sous Swing (Java).
J'ai créé un textArea qui affiche une liste d'objets (via leur méthode toString() + "\n" ) avec 1 item par ligne
Je souhaite pouvoir récupérer le contenu de chaque ligne via un listener de type MouseEvent.

La documentation du net m'a orienté vers du code de cette forme :

int line = prt_list.getLineOfOffset(prt_list.getCaretPosition());
int start = prt_list.getLineStartOffset(line);
int end = prt_list.getLineEndOffset(line);
String text = prt_list.getDocument().getText(start, end);

Il s'avère que cette méthode ne me permet que de récupérer la première ligne de mon textArea.
Pour toute autre ligne j'ai droit à un BadLocationException.

J'ai pensé à un moment que le souci était en lien avec mon affichage : je réalise un "append" de mes objets dans le textarea --> du coup j'ai concatené mes objets dans une String pour le restituer dans le textArea : même résultat.
Ma variable line est donc erronnée et je ne sais pas pourquoi :-(

Auriez-vous une/des pistes pour me permettre de résoudre cette  butée?

Merci d'avance

1 réponse

ozone_ Messages postés 1518 Date d'inscription lundi 13 juillet 2009 Statut Membre Dernière intervention 2 juin 2023 478
1 mai 2023 à 16:30

Bonjour,

Il semble que le problème vient du fait que la méthode getLineStartOffset() et getLineEndOffset() prennent en paramètre un offset, qui est une position dans le document, et non un numéro de ligne. Ainsi, si vous appelez ces méthodes avec le numéro de ligne, cela peut entraîner des exceptions BadLocationException.

Pour récupérer le contenu de chaque ligne en fonction du MouseEvent, vous pouvez utiliser la méthode viewToModel() de la classe JTextComponent pour convertir les coordonnées de la souris en un offset dans le document. Vous pouvez ensuite utiliser la méthode getLineOfOffset() pour obtenir le numéro de ligne correspondant à cet offset, puis utiliser les méthodes getLineStartOffset() et getLineEndOffset() pour récupérer le contenu de cette ligne.

Voici un exemple de code qui devrait vous aider à résoudre votre problème :

prt_list.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        JTextComponent textComp = (JTextComponent)e.getSource();
        int offset = textComp.viewToModel(e.getPoint());
        try {
            int line = textComp.getLineOfOffset(offset);
            int start = textComp.getLineStartOffset(line);
            int end = textComp.getLineEndOffset(line);
            String text = textComp.getDocument().getText(start, end - start);
            System.out.println(text); // affiche le contenu de la ligne cliquée
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }
    }
});

Notez que l'événement MouseEvent est déclenché lorsque vous cliquez sur le composant (ici, le JTextArea), donc lorsque vous cliquez sur une ligne spécifique, le contenu de cette ligne sera affiché dans la console.

J'espère que cela vous aidera à résoudre votre problème. N'hésitez pas à me faire savoir si vous avez besoin de plus d'informations ou si vous avez d'autres questions.

Source: ChatGPT


0
arscy Messages postés 173 Date d'inscription dimanche 26 janvier 2014 Statut Membre Dernière intervention 5 octobre 2023 9
Modifié le 1 mai 2023 à 17:25

Au vu de ce que j'ai saisi de votre code le clic s'applique à ma fenêtre entière, ce qui ne m'arrange pas forcément.
J'ai néanmoins conservé la notion de viewToModel en le couplant à deux boucles while pour parcourir le texte en amont et en aval afin d'isoler la ligne (chercher le début du texte, un saut de ligne ou bien la fin du texte), et l'esclave des temps modernes que vous avez utilisé comme référence précédemment a complété la donne.
Merci pour la suggestion

Ça donne quelque chose du genre :

int caretPosition = prt_list.viewToModel2D(e.getPoint());
int start = caretPosition;
int end = caretPosition;

try {
   while(start >0 && prt_list.getText().charAt(start - 1) != '\n'){
      start--;
   }
   while(end < prt_list.getText().length() && prt_list.getText().charAt(end) != '\n'){
      end++;
   }
String text = prt_list.getText().substring(start, end);
   } catch (BadLocationException x){
      /*...*/
}
0