J'ai un JTextField dans mon application swing qui contient le chemin d'accès d'un fichier sélectionné pour être utilisé. Actuellement, j'ai un JFileChooser qui est utilisé pour remplir cette valeur. Cependant, je voudrais ajouter la possibilité pour un utilisateur de glisser-déposer un fichier sur ce JTextField et de lui faire placer le chemin d'accès de ce fichier dans le JTextField au lieu de toujours utiliser le JFileChooser.
Comment cela peut-il être fait?
Vous devez d'abord examiner Prise en charge de Swing DragDrop . Après cela, il y a quelques petites astuces pour différents systèmes d'exploitation. Une fois que vous avez commencé, vous allez gérer le rappel drop (). Dans ce rappel, vous voudrez vérifier la DataFlavor du transférable.
Pour Windows, vous pouvez simplement vérifier le DataFlavor.isFlavorJavaFileListType () puis obtenir vos données comme ceci
List<File> dropppedFiles = (List<File>)transferable.getTransferData(DataFlavor.javaFileListFlavor)
Pour Linux (et probablement Solaris), DataFlavor est un peu plus délicat. Vous devrez créer votre propre DataFlavor et le type transférable sera différent
nixFileDataFlavor = new DataFlavor("text/uri-list;class=Java.lang.String");
String data = (String)transferable.getTransferData(nixFileDataFlavor);
for(StringTokenizer st = new StringTokenizer(data, "\r\n"); st.hasMoreTokens();)
{
String token = st.nextToken().trim();
if(token.startsWith("#") || token.isEmpty())
{
// comment line, by RFC 2483
continue;
}
try
{
File file = new File(new URI(token))
// store this somewhere
}
catch(...)
{
// do something good
....
}
}
Il existe un exemple de programme qui contient une classe qui peut être utilisée pour faciliter le glisser-déposer des fichiers et des dossiers:
http://www.iharder.net/current/Java/filedrop/
J'ai testé cela avec Windows 7 et Ubuntu 10.10, et cela semble bien fonctionner dans les deux environnements.
Pour l'utiliser, vous ajoutez quelque chose comme ça à votre code:
JPanel myPanel = new JPanel();
new FileDrop( myPanel, new FileDrop.Listener()
{ public void filesDropped( Java.io.File[] files )
{
// handle file drop
...
} // end filesDropped
}); // end FileDrop.Listener
Si vous ne voulez pas passer trop de temps à rechercher ce sujet relativement complexe et que vous utilisez Windows (ou utilisez Java 7 ou version ultérieure), voici un exemple rapide sur la façon d'accepter fichiers déposés avec un JTextArea comme cible de dépôt:
JTextArea myPanel = new JTextArea();
myPanel.setDropTarget(new DropTarget() {
public synchronized void drop(DropTargetDropEvent evt) {
try {
evt.acceptDrop(DnDConstants.ACTION_COPY);
List<File> droppedFiles = (List<File>)
evt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
for (File file : droppedFiles) {
// process files
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
Je sais que c'est une vieille question mais les réponses actuelles sont toutes un peu dépassées:
Cela fonctionne sous Linux (KDE5) et Windows 7:
final class FileDropHandler extends TransferHandler {
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
for (DataFlavor flavor : support.getDataFlavors()) {
if (flavor.isFlavorJavaFileListType()) {
return true;
}
}
return false;
}
@Override
@SuppressWarnings("unchecked")
public boolean importData(TransferHandler.TransferSupport support) {
if (!this.canImport(support))
return false;
List<File> files;
try {
files = (List<File>) support.getTransferable()
.getTransferData(DataFlavor.javaFileListFlavor);
} catch (UnsupportedFlavorException | IOException ex) {
// should never happen (or JDK is buggy)
return false;
}
for (File file: files) {
// do something...
}
return true;
}
}
Utilisez-le sur n'importe quel composant avec
myComponent.setTransferHandler(new FileDropHandler());