Ajuster le fichier sélectionné à FileFilter dans un JFileChooser
Je suis en train d'écrire un éditeur de diagramme en java. Cette application a la possibilité d'exporter vers différents formats d'image standard tels que .jpg, .png, etc. Lorsque l'utilisateur clique sur Fichier->Export, vous obtenez un JFileChooser
qui a un certain nombre de FileFilter
s, pour .jpg
.png
etc.
Maintenant, voici ma question:
Est-il un moyen d'avoir l'extension par défaut d'ajuster le fichier sélectionné filtre? E. g. si le document est nommé "lolcat", puis l'option par défaut doit être "lolcat.png" lorsque le png filtre est sélectionné, et lorsque l'utilisateur sélectionne le fichier jpg de filtre, la valeur par défaut doit changer "lolcat.jpg" automatiquement.
Est-ce possible? Comment puis-je le faire?
edit:
Basé sur la réponse ci-dessous, j'ai écrit un peu de code. Mais il ne fonctionne pas encore. J'ai ajouté un propertyChangeListener
à la FILE_FILTER_CHANGED_PROPERTY
, mais il semble que cette méthode getSelectedFile()
renvoie la valeur null. Voici le code.
package nl.helixsoft;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter;
public class JFileChooserTest {
public class SimpleFileFilter extends FileFilter {
private String desc;
private List<String> extensions;
private boolean showDirectories;
/**
* @param name example: "Data files"
* @param glob example: "*.txt|*.csv"
*/
public SimpleFileFilter (String name, String globs) {
extensions = new ArrayList<String>();
for (String glob : globs.split("\\|")) {
if (!glob.startsWith("*."))
throw new IllegalArgumentException("expected list of globs like \"*.txt|*.csv\"");
//cut off "*"
//store only lower case (make comparison case insensitive)
extensions.add (glob.substring(1).toLowerCase());
}
desc = name + " (" + globs + ")";
}
public SimpleFileFilter(String name, String globs, boolean showDirectories) {
this(name, globs);
this.showDirectories = showDirectories;
}
@Override
public boolean accept(File file) {
if(showDirectories && file.isDirectory()) {
return true;
}
String fileName = file.toString().toLowerCase();
for (String extension : extensions) {
if (fileName.endsWith (extension)) {
return true;
}
}
return false;
}
@Override
public String getDescription() {
return desc;
}
/**
* @return includes '.'
*/
public String getFirstExtension() {
return extensions.get(0);
}
}
void export() {
String documentTitle = "lolcat";
final JFileChooser jfc = new JFileChooser();
jfc.setDialogTitle("Export");
jfc.setDialogType(JFileChooser.SAVE_DIALOG);
jfc.setSelectedFile(new File (documentTitle));
jfc.addChoosableFileFilter(new SimpleFileFilter("JPEG", "*.jpg"));
jfc.addChoosableFileFilter(new SimpleFileFilter("PNG", "*.png"));
jfc.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent arg0) {
System.out.println ("Property changed");
String extold = null;
String extnew = null;
if (arg0.getOldValue() == null || !(arg0.getOldValue() instanceof SimpleFileFilter)) return;
if (arg0.getNewValue() == null || !(arg0.getNewValue() instanceof SimpleFileFilter)) return;
SimpleFileFilter oldValue = ((SimpleFileFilter)arg0.getOldValue());
SimpleFileFilter newValue = ((SimpleFileFilter)arg0.getNewValue());
extold = oldValue.getFirstExtension();
extnew = newValue.getFirstExtension();
String filename = "" + jfc.getSelectedFile();
System.out.println ("file: " + filename + " old: " + extold + ", new: " + extnew);
if (filename.endsWith(extold)) {
filename.replace(extold, extnew);
} else {
filename += extnew;
}
jfc.setSelectedFile(new File (filename));
}
});
jfc.showDialog(frame, "export");
}
JFrame frame;
void run() {
frame = new JFrame();
JButton btn = new JButton ("export");
frame.add (btn);
btn.addActionListener (new ActionListener() {
public void actionPerformed(ActionEvent ae) {
export();
}
});
frame.setSize (300, 300);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFileChooserTest x = new JFileChooserTest();
x.run();
}
});
}
}
source d'informationauteur amarillion
Vous devez vous connecter pour publier un commentaire.
Il semble que vous pouvez écouter de la
JFileChooser
pour un changement sur leFILE_FILTER_CHANGED_PROPERTY
de la propriété, puis changer l'extension du fichier sélectionné de façon appropriée à l'aide desetSelectedFile()
.EDIT: Vous avez raison, cette solution ne fonctionne pas. Il s'avère que lorsque le filtre de fichier est modifié, le fichier sélectionné est supprimé si son type de fichier ne correspond pas au nouveau filtre. C'est pourquoi vous obtenez la
null
lorsque vous essayez degetSelectedFile()
.Avez-vous envisagé d'ajouter l'extension plus tard? Quand je suis en train d'écrire un
JFileChooser
je l'habitude d'ajouter l'extension une fois que l'utilisateur a choisi un nom de fichier à utiliser et cliqué sur "Enregistrer":Vous pouvez également utiliser un PropertyChangeListener sur le SELECTED_FILE_CHANGED_PROPERTY avant de fixer votre suffixe. Lorsque le fichier est vérifié contre le nouveau filtre (et par la suite définie sur null), l'SELECTED_FILE_CHANGED_PROPERTY événement est en fait tiré avant la FILE_FILTER_CHANGED_PROPERTY événement.
Si l'evt.getOldValue() != null et l'evt.getNewValue() == null, vous savez que le JFileChooser a fustigé votre fichier. Vous pouvez alors récupérer l'ancien nom du fichier (à l'aide de ((Fichier)evt.getOldValue()).getName() comme décrit ci-dessus), tirez l'extension standard en utilisant des fonctions d'analyse de chaînes, et à ranger dans un nom de variable de membre au sein de votre classe.
De cette façon, lorsque le FILE_FILTER_CHANGED événement est déclenché (immédiatement après, aussi loin que je peux déterminer), vous pouvez tirer que planqué racine du nom de la variable membre, appliquer de l'extension pour le nouveau fichier type de filtre, et de définir le JFileChooser du fichier sélectionné en conséquence.
Voici ma solution et cela fonctionne très bien. Il peut-être aider quelqu'un. Vous devriez créer votre propre "MyExtensionFileFilter" de la classe, sinon, vous devez modifier le code.
Comment à ce sujet:
Voici une méthode pour obtenir le nom du fichier en cours (comme une Chaîne de caractères). Dans votre changement de propriété d'un écouteur pour
JFileChooser.FILE_FILTER_CHANGED_PROPERTY
à vous de faire l'appel suivant:La
getFileName()
méthode dejavax.swing.plaf.basic.BasicFileChooserUI
(le descendant deFileChooserUI
retourné parJFileChooser.getUI()
) retourne le contenu de la boîte de dialogue zone de texte qui est utilisé pour taper dans le nom de fichier. Il semble que cette valeur est toujours définie à une valeur non nulle de la Chaîne (elle renvoie une chaîne vide si la case est vide). D'autre part,getSelectedFile()
renvoie la valeur null si l'utilisateur n'a pas sélectionné un fichier existant encore.Il semble que la boîte de dialogue de conception est régi par la "sélection de fichier "concept"; c'est, alors que le dialogue est visible
getSelectedFile()
ne renvoie une valeur raisonnable si l'utilisateur a déjà sélectionné un fichier existant ou le programme appelésetSelectedFile()
.getSelectedFile()
sera de retour que l'utilisateur a tapé dans après l'utilisateur clique sur l'approuver (c'est à dire OK).La technique ne fonctionne que pour une seule sélection de boîtes de dialogue, en changeant l'extension de fichier basé sur le filtre sélectionné doit également avoir du sens pour un seul fichier ("Enregistrer sous..." dialogues ou similaire).
Cette conception a été un objet d'un débat au sun.com en 2003, voir la lien pour plus de détails.
L'utilisation de getAbsolutePath() dans le précédent changer le répertoire courant.
J'ai été surpris quand le JFileChooser boîte de dialogue affichage de "Mes documents" changement de répertoire pour Netbeans du répertoire de projet lorsque je choisi un autre FileFilter, donc je l'ai changé pour utiliser getName().
J'ai aussi utilisé le JDK 6 FileNameExtensionFilter.
Voici le code:
Voici ma tentative à cet égard. Il utilise le accept() pour vérifier si oui ou non le fichier traverse le filtre. Si le nom de fichier ne fonctionne pas, l'extension est ajouté à la fin.