2012-10-16 3 views
6

ablegen In meiner Eclipse RCP-Anwendung habe ich einen TreeViewer, der ein Drop-Ziel für Dateien ist, funktioniert es in den meisten Fällen aber, wenn ich es versuche und Ziehen von Dateien, die auf einer CD-ROM gespeichert sind, vom Windows Explorer zum Knoten. Das Symbol, das anzeigt, dass Drops erlaubt sind, ändert sich nicht und das Ablegen tut nichts.Warum kann ich nicht Dateien auf Eclipse/SWT Drop Target von einer CD in Windows

Da die Menschen schien verwirrt über meine Frage ist hier eine ausführlichere Erklärung:

Wenn Sie den nachfolgenden Code ausgeführt wird (geliefert von Baz), kann ich Dateien per Drag & Drop auf das Textfeld auf, wenn ich ziehen eine Datei von den meisten Orten auf meinem Rechner, erscheint das Fenster wie folgt aus ->

Working Drag

der Cursor zeigt an, dass ich fallen kann, und wenn ich die Maus die drop(DropTargetEvent event) Methode aufgerufen wird.

Nun, wenn ich das gleiche tun, aber eine Datei aus dem Explorer nehmen, die auf einer DVD in mein optisches Laufwerk ist dann sieht es wie folgt aus:

enter image description here

anzeigt, dass der Tropfen nicht erlaubt ist, und wenn ich die Maus loslasse, wird die drop(DropTargetEvent event) Methode NICHT aufgerufen.

Es ist auch erwähnenswert, dass ich die gleichen DVD-Dateien in einen Ordner im Eclipse-Navigator fallen lassen kann, was darauf hinweist, dass dies kein maschinenspezifisches Problem ist, da es in den Eclipse-Bäumen etwas anderes geben muss aber ich kann es nicht sehen.

package widgets; 

import java.util.Arrays; 

import org.eclipse.swt.SWT; 
import org.eclipse.swt.dnd.DND; 
import org.eclipse.swt.dnd.DropTarget; 
import org.eclipse.swt.dnd.DropTargetAdapter; 
import org.eclipse.swt.dnd.DropTargetEvent; 
import org.eclipse.swt.dnd.FileTransfer; 
import org.eclipse.swt.dnd.Transfer; 
import org.eclipse.swt.layout.GridData; 
import org.eclipse.swt.layout.GridLayout; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.swt.widgets.Text; 
import org.eclipse.ui.part.PluginTransfer; 

public class SourceTest { 
    public static void main(String[] args) { 
     final Display display = new Display(); 
     Shell shell = new Shell(display); 
     shell.setLayout(new GridLayout(1,false)); 

     final Text text = new Text(shell, SWT.BORDER); 
     text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); 

     DropTarget dt = new DropTarget(text, DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK); 
     dt.setTransfer(new Transfer[] { FileTransfer.getInstance(), PluginTransfer.getInstance() }); 
     dt.addDropListener(new DropTargetAdapter() { 
      public void drop(DropTargetEvent event) { 
       String fileList[] = null; 
       FileTransfer ft = FileTransfer.getInstance(); 
       if (ft.isSupportedType(event.currentDataType)) { 
        fileList = (String[]) event.data; 
       } 
       System.out.println(Arrays.toString(fileList)); 
      } 
     }); 

     shell.setSize(300, 100); 
     shell.open(); 

     while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) 
       display.sleep(); 
     } 
     display.dispose(); 
    } 

} 
+1

Haben Sie überprüft, ob sich der 'transferType' innerhalb der' validateDrop' Methode von dem beim Ablegen von der Festplatte unterscheidet? – Baz

+0

Sie sind TransferData-Objekte, die keine wesentlichen Unterschiede in der Struktur zu haben scheinen, aber die Operation scheint immer 16 für die ROM-Dateien zu sein, während für die Dateien, die funktionieren, die Operationen auf 2 über einen Knoten und 16 auf nicht wechseln. Das deutet darauf hin, dass der Knoten sich nicht als brauchbares Ziel für das, was gezogen wird, registriert. Es ist merkwürdig, dass ein Aufruf von validateDrop ausgeführt wird, obwohl es nicht die Absicht hat, Ihnen die Ausführung zu erlauben. – Link19

+0

Basierend auf dem Namen '** validate ** Drop()' macht es Sinn. Wird etwas forschen. Vielleicht finde ich eine Lösung. – Baz

Antwort

3

Es scheint, dass nicht alle möglichen DND-Operationen unterstützt werden, wenn sie von einem CD-ROM-Gerät kommen. Daher müssen Sie einige weitere Methoden auf der DropTargetAdapter implementieren, um die Drop-Operation während der Ausführung zu ändern, um die tatsächlich ausgeführten Operationen einzugrenzen, damit das Betriebssystem den Ausfall nicht verhindert.

nahm ich dein Beispiel und machte nur die kleine Änderung der DropTargetAdapter

@Override 
    public void dropAccept(DropTargetEvent event) 
    { 
     Object object = FileTransfer.getInstance().nativeToJava(event.currentDataType); 
     if(object instanceof String[]) 
     { 
      String[] strs = (String[]) object; 
      System.out.println("dropAccept " + strs[0]); 
      event.detail = DND.DROP_COPY; 
     } 
     event.detail = DND.DROP_COPY; 
    } 
    @Override 
    public void dragEnter(DropTargetEvent event) 
    { 
     event.detail = DND.DROP_COPY; 
    } 
+0

Das ist eine gute Arbeit, mein guter Freund. Also im wesentlichen das Detail überschreiben, um immer so zu erscheinen, als wäre es eine Kopie? Wird dies für andere Ereignistypen kein merkwürdiges Verhalten verursachen? – Link19

+0

So können Sie Code hinzufügen, um selektiver zu sein, wenn Sie dieses Ereignis "modifizieren". Ich füge meiner Antwort einen Code hinzu, der zeigt, wie man den Ort, an dem etwas fallen wird, "aufschnüffeln" kann und eine gewisse Entscheidung treffen kann, wann man etwas ändern und wann man alleine gehen soll. – gamerson

+0

Danke, ich werde sehen, ob ich das Äquivalent auch in den Eclipse Bäumen finden kann. – Link19

0

DND funktioniert nicht so, wie Sie denken, dass es funktioniert.

Betrachten Herunterladen einer Datei aus dem Web. Wenn Sie validieren herunterladen, gibt es keine tatsächlichen Datei Inhalt, aber Sie haben die nur URL einer Web-Ressource.

Wenn Sie die Drop-Operation validieren, können Sie die tatsächlichen Daten nicht kennen, da keine Verbindung besteht, bis Sie die Drop-Operation akzeptieren. Das einzige, was Sie in der Validierungsphase wissen können, ist die Übertragungsart.

So können Sie nur den Tropfen validieren auf den Inhalt Art basiert, nicht auf die „Ist-Content“

Typische Validierungscodes sind:

public boolean validateDrop(...){ 
    return FileTransfer.getInstance().isSupportedType(transferData); 
} 

Nachdem Sie „Transferdata“ akzeptieren, wird die Übertragung abrufen die tatsächlichen Daten von der Verbindung.

Also denken Sie daran, "TransferData" unterscheidet sich von den tatsächlichen Daten.

Die FileTransfer ruft die Dateien in den Forma eines String Array ab, das den absoluten Pfad zu jeder Datei enthält, nicht das Java File Objekt.

P.S .: Zwischenablage funktioniert auf die gleiche Weise.

+0

Danke, dass ich das alles wusste. Was schlägst du vor, ist die Antwort auf das Problem dann? – Link19

+0

Ich wundere mich, wer jede Antwort, die auf diese Frage gepostet wird downvoting ist ... – Baz

+0

Ich habe dies selbst abgelehnt, es ist eine detaillierte Information für sicher, aber es ist keine Antwort, jeeyul hat angenommen, dass ich nicht verstehe, wie Verwenden Sie Drag-Drop und erwartete nur, dass die Datei automatisch verschoben wird. Dies ist nicht der Fall. – Link19

1

denke ich, aktualisiert Ihre Frage stellt klar, was Problem ist.

Ihr Drop-Ziel verwendet DND_MOVE als Flag. Da wir Dateien in Nur-Lese-Medien wie DVD nicht entfernen können,

Absender (in diesem Fall, OS-Shell) wird DND-Kommunikation ablehnen, egal, ob die Entscheidung des Empfängers ist.

Screenshot von Ihnen zeigt Moving DND Feedback nicht Kopieren.

dropAccept() gibt Ihnen die letzte Chance, die Kommunikationsanforderung zu ändern, Verwenden Sie dies sorgfältig, da mehrere Drop-Ziel-Listener für jede Übertragungsart vorhanden sein können. Um diesen Fall zu unterstützen, unterscheiden sich die DND-APIs von TreeViewer geringfügig von denen von SWT.

Verwandte Themen