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

Composants Java Discussion :

[JTable] Implémentation comparator


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de miniil
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 267
    Par défaut [JTable] Implémentation comparator
    Bonjour,

    J'aimerai réaliser un filtre sur une colonne de ma JTable mais les résultats que ce filtre me ramène ne me convienne pas.

    En effet, je voudrais qu'on puisse introduire dans la zone de recherche (filtre) aussi bien le terme recherché en minuscule qu'en majuscule (ou même les deux).

    Le comparator par défaut est visible case sensitive, j'ai donc eut l'idée d'implémenter ma propre classe qui étend Comparator et qui implémente la fonction compare.

    Voici mon code pour cette classe :

    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
    public class MyComparatorLowerCaseForStringIntoTable implements Comparator<String>
    {
        public int compare(String o1, String o2)
        {
            try
            {
                final String s1 = o1.toLowerCase();
                final String s2 = o2.toLowerCase();
     
                System.out.println("First: " + s1 + "-  Second: " + s2);
     
                return s1.compareTo(s2);
            }
            catch(Exception e)
            {
                return 0;
            }
        }
     
    }
    Ensuite je fais ceci dans mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    model = new MyTableModel(titresCol, datas);
            offersListTable.setModel(model);
     
            offersListTable.setAutoCreateRowSorter(true);
            sorter = new TableRowSorter<MyTableModel>(model);
            offersListTable.setRowSorter(sorter);
            sorter.setSortsOnUpdates(true);
     
            MyComparatorLowerCaseForStringIntoTable myComparator = new MyComparatorLowerCaseForStringIntoTable();
            sorter.setComparator(2, myComparator);
    et ce bout de code pour le filtre suivant ce qui est introduit dans un TextField :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private void newFilterMarque()
        {
            RowFilter<MyTableModel, Object> rf = null;
            //If current expression doesn't parse, don't update.
            try
            {
                rf = RowFilter.regexFilter(marqueTextField.getText(), 2);
            }
            catch (java.util.regex.PatternSyntaxException e)
            {
                return;
            }
            sorter.setRowFilter(rf);
        }
    Mon problème...
    Ca ne fonctionne pas du tout.
    On ne passe jamais dans la méthode compare de la classe Comparator.
    Donc le filtre applique par défaut la comparaison case sensitive.

    Je ne vois pas où j'ai fait une erreur, alors si vous pouviez m'aider...

    D'avance merci.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Déjà je trouve que tu t'es bien embêté avec ton Comparator !
    Ceci aurait été amplement suffisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MyComparatorLowerCaseForStringIntoTable implements Comparator<String> {
    	public int compare(String o1, String o2) {
    		return o1.compareToIgnoreCase(o2);
    	}
    }
    Sans compter que tu aurais très bien pu utiliser celui en standard dans la classe String :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sorter.setComparator(2, String.CASE_INSENSITIVE_ORDER);
    A noter également qu'on pourrait se tourner vers les Collator, qui inclut des règles de trie spécifiques à une locale...



    Enfin tu mélanges les notions de "trie" et de "filtre".
    Le Comparator est utilisé uniquement pour trier les colonnes lorsque tu cliques sur l'entête.
    Il n'y a aucune raison de l'utiliser pour le filtre. Si tu veux avoir une notion case-insensitive lors du filtre tu dois le spécifier...

    Avec les expressions régulières cela se fait via "(?i)" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RowFilter.regexFilter("(?i)" + marqueTextField.getText(), 2);


    Au passage je ne sais pas ce que tu cherches à faire : les utilisateurs vont rentrer des expressions régulières ???
    Si c'est simplement pour filtrer par texte rapidement (sans expression régulière pour l'utilisateur), il faudrait protéger le text (afin d'éviter que certains caractères faussent le résultat ou génère des erreurs) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RowFilter.regexFilter("(?i)" + Pattern.quote( marqueTextField.getText() ), 2);
    Ou tu pourrais même implémenter ton propre RowFilter...


    a++

  3. #3
    Membre éclairé Avatar de miniil
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 267
    Par défaut
    Bonjour,

    Déjà, merci de ta réponse...

    En effet, j'ai mélanger la notion de tri et de filtre
    Il devait être trop tard hier pour réfléchir...

    Je note donc les deux solutions pour le filtre case incensitive

    En effet, ça marche très bien.

    Par contre, ce que tu dis au niveau des expressions régulières introduites par l'utilisateur pourrait être intéressant... Mais est-ce qu'il y a une possibilité de bien faire les choses en laissant à l'utilisateur la possibilité d'utiliser les wildcards comme par exemple : *montext* pour sélectionner tout ce qui contient montext ?

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Tel quel il faudrait que cela correspondent à une vrai expression régulière, ce qui n'est pas le cas dans ton exemple car le "*" s'applique sur l'élément précédent.

    Je suppose que tu veux utiliser les wildcards basiques des shells comme "*" et "?".

    Dans ce cas le moyen le plus simple serait de les convertir en vrai expression régulière, c'est à dire :
    • * est à remplacer par .*, c'est à dire zéro ou plusieurs fois n'importe quel caractère.
    • ? est à remplacer par ., c'est à dire n'importe quel caractère.



    Il faut également "quoter" la chaine afin que d'autres éventuels caractères spéciaux ne soient pas interprétés involontairement. En fait cela consiste simplement à mettre le texte entre \Q et \E afin qu'il ne soit pas interprété par le moteur de regexp.

    Il suffit ensuite de remplacer les */? par la regexp correspondante, en fermant/réouvrant les \Q \E comme il faut.

    Cela donne quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	public static String createRegexp(String glob, boolean caseInsensitive) {
    		String regexp = Pattern.quote(glob) // On protège la chaine par des \Q \E
    			.replace("*", "\\E.*\\Q") // On remplace les * par \E.*\Q
    			.replace("?", "\\E.\\Q") // On remplace les ? par \E.\Q
    			.replace("\\Q\\E", "");	 // On supprime les \Q\E inutile
    		if (caseInsensitive) 
    			return "(?i)" + regexp;
    		return regexp;
    	}
    Du coup ton expression *montext* correspondrait au pattern suivant : .*\Qmontext\E.*



    Après par défaut le RowFilter.regexFilter() recherche déjà la chaine où qu'elle soit. Si tu veux forcer la recherche du début il faut rajouter un ^ au début de ton pattern...


    a++

  5. #5
    Membre éclairé Avatar de miniil
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 267
    Par défaut
    Merci, je teste tout ça tout à l'heure

Discussions similaires

  1. Comparer 2 JTable
    Par said.aghzil dans le forum Débuter
    Réponses: 10
    Dernier message: 12/06/2013, 16h31
  2. Implémenter l’interface Comparable
    Par adrien881 dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 10/06/2011, 09h58
  3. Difficulter d'implémenter un JTable utilisant un model
    Par coolanso dans le forum Composants
    Réponses: 1
    Dernier message: 14/03/2011, 20h42
  4. Problème pour implémenter l'interface Comparable
    Par scheme dans le forum Langage
    Réponses: 15
    Dernier message: 29/01/2011, 19h31
  5. JTable(Netbeans) : Implémentation de getValueAt()
    Par maparè dans le forum Composants
    Réponses: 2
    Dernier message: 16/03/2010, 14h27

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