Je charge dans une combo le nom de sous-dossiers d'un dossier avec le code ci-dessous.
Je tente de classer par ordre alphabétique les noms avec un tableau de string et "Arrays.sort". Mais cela ne fonctionne pas. Pour info, dans la JComboBox, ce qui est affiché est Nom Prénom date de naissance (ex : JAVA jadore 22.03.2018)
Merci de votre aide.
public List<String> findFoldersInDirectory(String directoryPath) { File directory = new File(directoryPath);
FileFilter directoryFileFilter = new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } };
List<String> foldersInDirectory = new ArrayList<String>(directoryListAsFile.length); // liste des dossiers
effectivement
Collections.sort(foldersInDirectory);
tri bien par ordre alphabétique. Mais j'ai 2 problèmes :
1/ tous les noms sont affichés les uns à la suite des autres probablement en raison de cette déclaration
List<String> foldersInDirectory = new ArrayList<String>(directoryListAsFile.length); // liste des dossiers
Il faudrait voir le code modifié que tu as actuellement, parce que je ne comprends pas ce que tu veux dire pour tes problèmes 1 et 2, quant au 3 ça aurait du être réglé...
List<String> foldersInDirectory = new ArrayList<String>(directoryListAsFile.length); // liste des dossiers
for (File directoryAsFile : directoryListAsFile) {
foldersInDirectory.add(directoryAsFile.getName()); //on ajoute les dossiers au fur et à mesure à la liste
}
Collections.sort(foldersInDirectory); this.addItem(foldersInDirectory); //ajout à la combobox
return foldersInDirectory;
Avec ce code, le tri est bien effectué par ordre alphabétique, mais tous les noms sont les uns derrières les autres dans la combobox et il y a des crochets. Je ne peux donc rechercher un nom en autocompletion. Exemple ci-dessous :
Par contre avec le code ci-dessous, les noms ne sont pas triés par ordre alphabétiques mais par contre l'autocomplétion est possible car il n' a pas de crochets et de plus les noms sont les uns sous les autres
public List<String> findFoldersInDirectory(String directoryPath) {
File directory = new File(directoryPath); // chemin d'acces aux dossiers
FileFilter directoryFileFilter = new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } };
List<String> foldersInDirectory = new ArrayList<String>(directoryListAsFile.length); // liste des dossiers
for (File directoryAsFile : directoryListAsFile) {
foldersInDirectory.add(directoryAsFile.getName()); //on ajoute les dossiers au fur et à mesure à la liste this.addItem(directoryAsFile.getName()); //ajout à la combobox
}
// Collections.sort(foldersInDirectory); // this.addItem(foldersInDirectory); //ajout à la combobox
? C'est bizarre que tu ais une erreur maintenant quand tu essayes d'ajouter un File alors que tu as réussi à le faire avec une liste... qui n'était donc pas un String non plus !
Mais si tu veux convertir un objet en String tu peux utiliser la méthode toString(), ou des méthodes spécifiques à la classe File comme getName()
Comme tu n'as pas paramétré le JComboBox<E> il prends E=Object par défaut (confirmé par ton super(items) avec Object[] items) donc addItem(E) doit prendre un Object, c'est pour ça qu'il a accepté la List, il n'y a donc pas de raison qu'il refuse le File (et il affichera son toString par défaut, comme il l'a fait avec la List)
"J'ai omis de te donner la class complete : mais il y a toujours une erreur." Où est l'erreur dans "la class complete" que tu donnes ?
Ce code "complet" n'a rien à voir avec l'erreur dont on parlait avant...
pff ce bug m'exaspere ... J'en ai la tête qui va exploser. En fait j'ai tjrs la même erreur à savoir le type mistmatch
Type mismatch: cannot convert from element type String to File
en rapport avec :
Collections.sort(foldersInDirectory); for (File folderInDirectory: foldersInDirectory) combo1.addItem(folderInDirectory.toString());
dois je paramétrer le JComboBox<E ou dois je le laisser tel quel ? J'ai même déplacé ma méthode "public List<String> findFoldersInDirectory(String directoryPath) {" dans la class fenêtre mais rien n'y fait toujours la même erreur.
Est-ce que tu pourrais fournir ton code, totalement complet en une fois, pour que je puisse tester.
Parce que si combo1 est un JComboBox (implicitement JComboBox<Object>) alors tu manipules la méthode addItem(Object) donc que ce soit File ou String, les deux devraient être acceptés, tu as même réussi à y mettre une List<File> vu tes messages précédents...
Le problème est certainement ailleurs.
Voici la class permettant l'autocompletion dans laquelle j'ai inséré une méthode permettant de lister les dossiers dans la combo. Je remercie d'ailleurs les personnes permettant de mettre en ligne ces codes.
List<String> foldersInDirectory = new ArrayList<String>(directoryListAsFile.length); // liste des dossiers
Collections.sort(foldersInDirectory); for (File folderInDirectory: foldersInDirectory) this.addItem(folderInDirectory);
/* for (File directoryAsFile : directoryListAsFile) {
//foldersInDirectory.add(directoryAsFile.getName()); //on ajoute les dossiers au fur et à mesure à la liste // combo1.addItem(directoryAsFile.getName()); //ajout à la combobox combo1.addItem(foldersInDirectory); //ajout à la combobox // //this.addItem(foldersInDirectory);
le problème et je ne comprenais pas.
Mais en fait c'est le
for (File folderInDirectory : foldersInDirectory)
qui coince (et en relisant tes messages tu l'avais bien dit...)
Explication : foldersInDirectory est une List<String> donc Java attends à ce que folderInDirectory soit un String aussi.
Attention : dans ton code foldersInDirectory est une liste vide !
En effet, tu l'as créé à la bonne taille mais tu ne l'as jamais rempli.
File[] directoryListAsFile = directory.listFiles(directoryFileFilter);
List<String> foldersInDirectory = new ArrayList<String>(directoryListAsFile.length);
Collections.sort(foldersInDirectory);
for (File folderInDirectory : foldersInDirectory)
this.addItem(folderInDirectory);
Donc ici, tu va trier une liste vide, ce qui ne fera pas ce que tu veux.
Remarque : dans un modèle MVC il vaut mieux séparer la recherche et le tri des fichiers d'une part et l'ajout au combobox d'autre part.
Ici ta méthode devrait donc renvoyer en résultat l'ensemble des noms de fichiers triés (sans effet de bord sur la ComboBox). Et c'est en appelant cette méthode que tu ajoutes les items.
Voici une version "corrigée" de la méthode entière (à vérifier).
public SortedSet<String> findFoldersInDirectory(String directoryPath) {
SortedSet<String> sortedFoldersNameInDirectory = new TreeSet<String>();
for (File fileInDirectory : new File(directoryPath).listFiles())
if (fileInDirectory.isDirectory())
sortedFoldersNameInDirectory.add(fileInDirectory.getName());
return sortedFoldersNameInDirectory;
}
// et l'appel :
SortedSet<String> sortedFoldersNameInDirectory = findFoldersInDirectory("/Users/moi/eclipse-workspace/Doc JAVA/DOSSIERS");
for (String folderNameInDirectory : sortedFoldersNameInDirectory)
this.addItem(folderNameInDirectory);
Remarque : depuis Java 8 on pourrait aussi coder comme ceci :
public SortedSet<String> findFoldersInDirectory(String directoryPath) {
return Arrays.stream(new File(directoryPath).listFiles())
.filter(File::isDirectory).map(File::getName)
.collect(Collectors.toCollection(TreeSet::new));
}
// et l'appel :
findFoldersInDirectory("/Users/moi/eclipse-workspace/Doc JAVA/DOSSIERS")
.forEach(this::addItem);
Remarque : j'ai utilisé un TreeSet plutôt qu'un Collection.sort() parce que c'est plus efficace de garder un ensemble trié au fur et à mesure des ajouts que de trier une liste complète d'un coup.
Merci pour ta version corrigée, elle marche nickel !
Effectivement, en re-analysant mon code, la liste était vide et java attendant un string. Par contre, une question : j'ai pu lire :
Les Set sont particulièrement adaptés pour manipuler une grande quantité de données. Cependant, les performances de ceux-ci peuvent être amoindries en insertion. Généralement, on opte pour un HashSet, car il est plus performant en temps d'accès, mais si vous avez besoin que votre collection soit constamment triée, optez pour un TreeSet.
Dans mon cas, avec plusieurs centaines de dossiers, ne faudrait-il pas une hashset ?
"si vous avez besoin que votre collection soit constamment triée, optez pour un TreeSet." C'est ce que j'expliquais dans ma dernière remarque.
Ta question concerne le tri, si tu utilises un HashSet ce ne sera pas trié, d'où le TreeSet.
PS. Quand on parle de "grande quantité de données" ce n'est pas une centaine de valeurs (comme le nombre de sous-dossiers dans un dossier) c'est beaucoup plus.
Et si tu avais effectivement une "grande quantité de données" il serait inefficace de toutes les mettre dans une JComboBox.
Mais en fait c'est le qui coince (et en relisant tes messages tu l'avais bien dit...)
Explication : foldersInDirectory est une List<String> donc Java attends à ce que folderInDirectory soit un String aussi.
Attention : dans ton code foldersInDirectory est une liste vide !
En effet, tu l'as créé à la bonne taille mais tu ne l'as jamais rempli.
Donc ici, tu va trier une liste vide, ce qui ne fera pas ce que tu veux.
Remarque : dans un modèle MVC il vaut mieux séparer la recherche et le tri des fichiers d'une part et l'ajout au combobox d'autre part.
Ici ta méthode devrait donc renvoyer en résultat l'ensemble des noms de fichiers triés (sans effet de bord sur la ComboBox). Et c'est en appelant cette méthode que tu ajoutes les items.
Voici une version "corrigée" de la méthode entière (à vérifier).
Remarque : depuis Java 8 on pourrait aussi coder comme ceci :
Remarque : j'ai utilisé un TreeSet plutôt qu'un Collection.sort() parce que c'est plus efficace de garder un ensemble trié au fur et à mesure des ajouts que de trier une liste complète d'un coup.
Effectivement, en re-analysant mon code, la liste était vide et java attendant un string. Par contre, une question : j'ai pu lire :
Les Set sont particulièrement adaptés pour manipuler une grande quantité de données. Cependant, les performances de ceux-ci peuvent être amoindries en insertion. Généralement, on opte pour un HashSet, car il est plus performant en temps d'accès, mais si vous avez besoin que votre collection soit constamment triée, optez pour un TreeSet.
Dans mon cas, avec plusieurs centaines de dossiers, ne faudrait-il pas une hashset ?
C'est ce que j'expliquais dans ma dernière remarque.
Ta question concerne le tri, si tu utilises un HashSet ce ne sera pas trié, d'où le TreeSet.
PS. Quand on parle de "grande quantité de données" ce n'est pas une centaine de valeurs (comme le nombre de sous-dossiers dans un dossier) c'est beaucoup plus.
Et si tu avais effectivement une "grande quantité de données" il serait inefficace de toutes les mettre dans une JComboBox.