Sélectionner des mots dans un jtextArea (l'équivalent du CTRL+F)

Résolu
Hssy23 Messages postés 7 Date d'inscription jeudi 16 octobre 2014 Statut Membre Dernière intervention 18 août 2015 - Modifié par hanou23 le 16/10/2014 à 18:23
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 - 6 nov. 2014 à 23:57
Bonjour,

j'ai un textArea et un menuItem. Je souhaite, lorsque je click sur le menuItem, un jOptionPane s'affiche( contient un textField et un bouton) et lorsque je tape un mot dans le textField et je clique sur le bouton toute les mots du textArea qui correspondent au mot entrée par l'utilisateur seront sélectionnés.

j'ai déjà essayé de programmer ça mais à chaque fois le programme sélectionne seulement le premier mot qu'il trouve.

voiçi mon code :

private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt)
{
String ValeurTexte=jTextArea2.getText();
int k =0;

JOptionPane jop = new JOptionPane();

String m = jop.showInputDialog(null,"Search :", "Search", JOptionPane.PLAIN_MESSAGE);

while (k <= ValeurTexte.length())
{
int start = ValeurTexte.indexOf(m);
int ind = start + m.length();

jTextArea2.select(start,ind);

k++;

}
}
j'attend votre aide :)
Merci d'avance.

2 réponses

Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
17 oct. 2014 à 10:59
Salut,

Si j'ai bien compris ta question je pense que le petit exemple ci-après répondra à ton besoin:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;

public class SearchWindow extends JFrame implements ActionListener {
  private static final long                  serialVersionUID = 2017911805149871896L;
  // Code important
  /* HighlightPainter utilisé pour mettre en évidence le mot à chercher */
  private final Highlighter.HighlightPainter hPainter         = new HPainter(Color.YELLOW);
  
  
  // Code pour l'exemple
  private JTextArea                          area             = null;
  private JButton                            bSearch          = null;
  private JTextField                         tSearch          = null;

  public SearchWindow() {
    // Code pour l'exemple
    /* Pour la zone de recherche */
    final JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
    bSearch = new JButton("Search");
    bSearch.addActionListener(this);
    tSearch = new JTextField();
    tSearch.setPreferredSize(new Dimension(630, 25));
    panel.add(new JLabel("Search: "));
    panel.add(tSearch);
    panel.add(bSearch);
    getContentPane().add(panel, BorderLayout.NORTH);

    // Code pour l'exemple
    /* Pour la zone de texte */
    area = new JTextArea();
    final JScrollPane pane = new JScrollPane(area);
    pane.setPreferredSize(new Dimension(800, 500));
    getContentPane().add(pane, BorderLayout.CENTER);
    // Code pour l'exemple
    /* init de la fenêtre */
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    pack();
    setLocationRelativeTo(null);
  }

  // Code pour l'exemple
  public static void main(final String[] args) {
    /* init et affichage de la fenêtre */
    new SearchWindow().setVisible(true);
  }

  // Code pour l'exemple
  @Override
  public void actionPerformed(final ActionEvent e) {
    /* action sur le bouton */
    if (e.getSource().equals(bSearch)) {
      // Code important
      /* sur brillance des mots */
      addHighlight(area, tSearch.getText());
    }
  }

  // Code important
  // Ajout un HighlightPainter de type HPainter sur toutes les occurrences "word"
  public void addHighlight(final JTextComponent tcomp, final String word) {
    // Supprime les anciens
    removeHighlights(tcomp);

    try {
      final Highlighter h = tcomp.getHighlighter();
      final Document doc = tcomp.getDocument();
      final String fullText = doc.getText(0, doc.getLength());
      int pos = 0;

      // Recherche du "word"
      while ((pos = fullText.indexOf(word, pos)) >= 0) {
        // Ajout du nouveau painter
        h.addHighlight(pos, pos + word.length(), hPainter);
        // On avance pour la suite
        pos += word.length();
      }
    } catch (final BadLocationException e) {
      e.printStackTrace();
    }

  }
  
  // Code important
  // Supprime les HighlightPainter de type HPainter
  public void removeHighlights(final JTextComponent textComp) {
    final Highlighter her = textComp.getHighlighter();
    final Highlighter.Highlight[] h = her.getHighlights();
    for (int i = 0; i < h.length; ++i) {
      // Si c'est le notre on delete
      if (HPainter.class.isInstance(h[i].getPainter()))
        her.removeHighlight(h[i]);
    }
  }
  // Code important
  // Le passage par une classe privée permet d'isoler nos HighlightPainter au
  // moment du remove
  class HPainter extends DefaultHighlighter.DefaultHighlightPainter {
    public HPainter(final Color color) {
      super(color);
    }
  }
}


Utilisation:
- Exécute le code.
- Tape (ou copie/colle) du texte dans le JTextArea.
- Tape un mot dans la zone de recherche.
- Clic sur le bouton "Search"
- Applause... :)


0
Salut,

si je veux modifier ce code pour que la sélection de l'occurrence suivante du mot s'effectue suite à un click sur un bouton "suivant" et ainsi de suite pour les autres occurrences ...

Qu'est ce que je dois rajouter pour que ça fonctionne comme la recherche dans un fichier pdf (avec ctrl+F) c'est à dire a l'aide des deux boutons "suivant" et "précédent"?

J'ai essayé tant de fois mais je n'ai pas trouvé une solution :(

Merci de m'aider.
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
20 oct. 2014 à 15:13
Salut,

Ok, ok si on reprend le code ci-dessus ça donne, le suivant donne:
public class SearchWindow extends JFrame implements ActionListener {
...
  private int                                old_pos          = 0;
...
public void addHighlight(final JTextComponent tcomp, final String word) {
    // Supprime les anciens
    removeHighlights(tcomp);

    try {
      final Highlighter h = tcomp.getHighlighter();
      final Document doc = tcomp.getDocument();
      final String fullText = doc.getText(0, doc.getLength());
      int pos = old_pos;
      if((pos = fullText.indexOf(word, pos)) < 0)
         pos = old_pos = fullText.indexOf(word, 0);
      // Recherche du "word"
      // Ajout du nouveau painter
      h.addHighlight(pos, pos + word.length(), hPainter);
      // On avance pour la suite
      pos += word.length();
      old_pos = pos;
      
    } catch (final BadLocationException e) {
      e.printStackTrace();
    }

  }
...


Avec cette modification tu vas boucler sur le mot recherché.
Du coup je te laisse réfléchir à "comment faire le précédent".
0
Bonjour Twinuts,

En fait,ce que vous m'avez proposé est bien fonctionnel mais il reste un petit problème vu que le texte où je veux effectuer la recherche est très long donc parfois je n'arrive pas à voir le résultat que lorsque je parcours le texte avec "l'ascenseur"

Je me demande s'il y a une solution pour que "l'ascenseur" se déplace automatiquement avec l'occurrence suivante du mot.

Merci infiniment pour votre aide.
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
27 oct. 2014 à 08:17
Salut,

normalement il suffit de déplacer le caret du text area.
...
  public void addHighlight(final JTextComponent tcomp, final String word) {
    ...
    try {
      ...
      if((pos = fullText.indexOf(word, pos)) < 0)
         pos = old_pos = fullText.indexOf(word, 0);
      // Déplacement du caret.
      area.setCaretPosition(pos);
      ...
    } catch (final BadLocationException e) {
      e.printStackTrace();
    }
  }
...
0
Hssy23 Messages postés 7 Date d'inscription jeudi 16 octobre 2014 Statut Membre Dernière intervention 18 août 2015
Modifié par Twinuts le 6/11/2014 à 23:42
Salut Twinuts,

j'ai essayé de programmer le bouton "précédent" et j'ai trouvé une solution mais il y 'a un petit problème : lorsque j'exécute le programme il m'affiche seulement la première occurrence précédente qu'il trouve dans le texte et il se bloque dans cette position.

voici le code ..
  public void addHighlightPrecedent(final JTextComponent tcomp2, final String word2) { 
    removeHighlights(tcomp2); 

    try { 
      final Highlighter h = tcomp2.getHighlighter(); 
      final javax.swing.text.Document doc = tcomp2.getDocument(); 
      String fullText = doc.getText(0,old_posNext- word2.length()); 
      int pos = old_posPrecedent; 
      System.out.println(pos); 
      if((pos = fullText.lastIndexOf(word2, pos)) <0) 
        JOptionPane.showMessageDialog(null, "impossible de trouver le mot","information",JOptionPane.INFORMATION_MESSAGE); 
      pos=fullText.lastIndexOf(word2, pos); 
      System.out.println("pos avant : "+pos); 
      jTextArea2.setCaretPosition(pos); 
      h.addHighlight(pos, pos + word2.length(), hPainter); 
      System.out.println("pos aprés : "+pos); 
      old_posPrecedent = pos ; 

    } catch (final BadLocationException e) { 
      e.printStackTrace();} 
  } 

Sachant que "old_posPrecedent" contient la dernière position du bouton "Next" avant l'ajout de la taille du mot.

Merci d'avoir m'aider pour corriger l'erreur.


EDIT Twinuts: Merci de bien vouloir utiliser la balise code.
0
Hssy23 Messages postés 7 Date d'inscription jeudi 16 octobre 2014 Statut Membre Dernière intervention 18 août 2015
17 oct. 2014 à 13:21
Salut Twinuts,

ça marche convenablement .. ^^

merci infiniment pour votre aide :)
0
Rejoignez-nous