IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SWT/JFace Java Discussion :

[JFace] Comment optimiser une recherche dans un TableViewer ?


Sujet :

SWT/JFace Java

  1. #1
    Membre confirmé Avatar de desert
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2007
    Messages : 414
    Points : 479
    Points
    479
    Par défaut [JFace] Comment optimiser une recherche dans un TableViewer ?
    Bonjour à tous et à toutes,
    Je réalise en ce moment une application dans laquelle grâce à un champ Text et un Button, j'arrive à filtrer les objets contennant en partie le mot tapé dans la zone texte.
    Le problème est que je me retrouve au départ avec plus de 6000 objets (de type Personne possèdant un attribut id et un attribut nom). Imaginez donc le temps qu'il faut pour rechercher un mot précis dans tout cela ! Résultat : cela prend entre 2 et 3s.
    Ma question au final est donc : Comment feriez-vous pour optimiser cette recherche ?

    Voici la classe qui se charge de filtrer le TableViewer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class PersonneNomFilter extends ViewerFilter {
       private String nomPersonne;
     
       public PersonneNomFilter(String nomPersonne) {
          this.nomPersonne = nomPersonne;
       }
       public void setText(String nomPersonne) {
          this.nomPersonne = nomPersonne;
       }
       public boolean select(Viewer viewer, Object parent, Object element) {
         if(nomPersonne.length() == 0) 
            return true;
         else {
            Personne p = (Personne) element;
            String str = p.getNom().toUpperCase();
            if(str.indexOf(nomPersonne.toUpperCase()) >= 0) 
               return true;
            return false;
         }
       }
    }

  2. #2
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    340
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 340
    Points : 379
    Points
    379
    Par défaut
    Tu ne devrais pas utiliser le ViewFilter puisqu'il va forcement parcourir tous les objets.
    Il va falloir que tu tries les éléments "recherchable" afin de pouvoir les retrouver rapidement, la complexité d'un algo de recherche sur un ensemble trié peut être en log2(n), avec n le nombre d'élément, donc petit calcul log2(6000) = 12,... ! donc quelque chose de l'ordre d'une dizaine d'opération pour trouver un mot alors que là tu en fait 6000, tu vas même pouvoir te passer du bouton "rechercher" en simplement ajouter un ModifyListener à ton champs de text pour faire les recherches en temps réel au fur et à mesure que l'utilisateur tappe du texte.

  3. #3
    Membre confirmé Avatar de desert
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2007
    Messages : 414
    Points : 479
    Points
    479
    Par défaut
    Merci pour l'aide.
    En fait, je ne vois pas comment faire cela sans ViewFilter comme tu le proposes.
    Comment effectuer ce tri sans parcourir les objets chacun à leur tour ?
    Pourrais-tu étayer un peu plus stp ?
    J'ai essayé avec un ModifyListener et un ViewerFilter mais à la première lettre tapée, le temps est encore trop long (ce qui est normal).

  4. #4
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    340
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 340
    Points : 379
    Points
    379
    Par défaut
    Eh bien tu dois parcourir une première fois tous les éléments pour les trier (tu peux pas y couper mais bon tu peux ne le faire qu'une seule fois pour toute l'appli si le contenu ne change pas).

    Ensuite tu récupères le texte entré par l'utilisateur et tu effectue une recherche dans tes éléments.

    Java fourni des structures qui sont automatiquement triées en utilisant des éléments qui implémentent l'interface Comparable ou en utilisant un Objet de type Comparable pour les comparer (puisque qui dit tri dit comparaison entre les élément pour les disposer correctement).
    Regarde du côté de TreeSet ou TreeMap qui fournissent des structures qui sont automatiquement triées, tu n'as plus qu'à y ajouter tes élément.
    Sinon tu peux aussi utiliser des collections simples comme ArrayList ou LinkedList et appliquer la méthode statique sort(Collection) de la class Collections il me semble qui implémente un algorithme de tri rapide.

    Voilà je te laisse potasser un peu tient moi au courant.

  5. #5
    Membre confirmé Avatar de desert
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2007
    Messages : 414
    Points : 479
    Points
    479
    Par défaut
    J'ai résolu le problème.
    Ce que j'ai fait: J'ai simplement créé une liste temporaire qui se charge de stocker tous les objets qui contiennent les lettres tapées.
    Il suffit ensuite d'affecter cette liste temporaire au TableViewer grâce au setInput.
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    String str, nom;
    Personne p;
    for(int i = 0; i < listePrincipale.size(); i++) {
       str = text.getText().toLowerCase();
       p = listePrincipale.get(i);
       nom = p.getNom().toLowerCase();
       if(nom.indexOf(str) >= 0) {
          listeTemp.add(p);
       }
    }
    tableViewer.setInput(temp);
    Résultat: max 450ms pour une première lettre.
    J'aurais pû pousser un peu plus loin la chose en recherchant successivement dans la liste temporaire mais je vais me contenter de ceci pour l'instant.

    PS: Merci pour l'approfondissement soft0613.

  6. #6
    Membre régulier
    Inscrit en
    Août 2008
    Messages
    142
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 142
    Points : 71
    Points
    71
    Par défaut
    Slt desert, c'est encore moi

    Je m'incruste dans ton sujet car dans le cadre de ma fameuse application que je fais en ce moment, je dois pouvoir réaliser un filtre sur ma table./ Pour rappel, Je peuple ma table via des données provenant de l'éxecution d'une procédure stockée dans une base de données.

    Je voudrais donner la possibilité à l'utilisateur de pouvoir effectuer des filtres sur les colonnes qui seront générées. J'envisage disposer de deux vues. La première dans la quelle j'aurais des objets(zone de texte, boutons à cocher, ...) me permettant d'éffectuer mon filtre; et la seconde (en dessous de la première) dans la quelle j'afficherais mes données en reponse aux informations du filtre.

    Pour l'instant, grâce entre autre à l'excellent tutoriel de keukeul, j'arrive à appliquer un filtre (simple zone de recherche) sur ma table en utilisant le ViewerFilter. Mes préoccupations sont donc les suivantes :

    - Est ce qu'il vaut mieux passer par plusieurs ViewerFilter, chacun lié à une condition sur une colonne. Sachant que je peux avoir comme conditions le fait de rechercher une sous chaine, de faire des filtres sur des montants (< > =) ...

    - Est ce qu'il vaut mieux ajouter un bouton dont le clic effecturais tous les filtres qui auraient été spécifiés dans la vue des filtres?

    Merci de votre aide.

  7. #7
    Membre confirmé Avatar de desert
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2007
    Messages : 414
    Points : 479
    Points
    479
    Par défaut
    Salut,
    Citation Envoyé par papaetoo
    - Est ce qu'il vaut mieux passer par plusieurs ViewerFilter, chacun lié à une condition sur une colonne. Sachant que je peux avoir comme conditions le fait de rechercher une sous chaine, de faire des filtres sur des montants (< > =) ...
    Oui, surtout si tu as beaucoup de conditions.
    Citation Envoyé par papaetoo
    - Est ce qu'il vaut mieux ajouter un bouton dont le clic effecturais tous les filtres qui auraient été spécifiés dans la vue des filtres?
    C'est à toi de voir. Personnellement, je trouverais plus pratique de ne pas en ajouter car moins de manipulations à faire pour au final faire la même chose.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment faire une recherche dans un fichier?
    Par djisse dans le forum Entrée/Sortie
    Réponses: 15
    Dernier message: 20/07/2009, 15h27
  2. COmment faire une recherche dans tous les dossiers
    Par Djohn dans le forum Outlook
    Réponses: 2
    Dernier message: 28/06/2007, 19h27
  3. Réponses: 5
    Dernier message: 03/08/2006, 08h03
  4. Comment faire une recherche dans ACCESS
    Par Bass_Room dans le forum Access
    Réponses: 2
    Dernier message: 02/06/2006, 10h51
  5. Comment effectuer une recherche dans une listBox?
    Par Mickey.jet dans le forum Delphi .NET
    Réponses: 2
    Dernier message: 19/05/2006, 16h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo