AWT Drag n Drop-Support für Component

Milgo

Mitglied
Tach,

ich bin schon was länger an nem Java-Programm dran und wollte jetzt auch Drag and Drop-Support einbauen, aber mir ist das ein wenig zu hoch, bei den ganzen Anleitungen fehlen mir immer ein paar Informationen, die ihr mir hoffentlich geben könnt. :)

Ich möchte dabei zwei verschiedene Arten von Support erreichen. Zum einen habe ich eine eigene Label-Klassen gebaut die ein wenig an Zusatzinformationen haben. Ich möchte Objekte dieser Labels nun auf andere Objekte der selben Klasse ziehen können um dann mit beiden Labels weiterzuarbeiten.

Andererseits möchte ich auch gerne JPanels in einem GridLayout mithilfe von Drag and Drop in der Anzeige-Reihenfolge verändern können.

Ich habe mir auch schon alles mögliche zu dem Thema durchgelesen (bitte also nicht einfach stur auf Google verweisen). Jetzt zu den Fragen, die sich mir aufgetan haben.

1. Ich vermute, dass ich das Interface Transferable für die Drag-Quelle benötige, ist das richtig? Und was ist in dem Interface dieses DataFlavor?
2. Benötige ich das Interface DropTargetListener für das Drop-Ziel? Die drop-Methode sieht ja ziemlich nach dem aus, was ich benutzen möchte.
3. Benötige ich für mein Vorhaben einen eigenen TransferHandler? Welche Methoden von der Klasse sollte ich denn dann überschreiben?
4. Wie schaffe ich es denn, dass man eine meiner Component-Klassen überhaupt draggen kann? Da fehlt mir irgendwie noch komplett der Ansatz.

Vielen Dank für die Hilfe! :)
 

André Uhres

Top Contributor
Hallo Milgo, willkommen im Forum!
Benutze Swing und nicht AWT: also z.B. JLabel statt Label, JPanel statt Panel, usw.
Beim Drag and Drop musst Du einen TransferHandler (extends TransferHandler) und einen Transferable (implements Transferable) implementieren.
Den TransferHandler bindest du einfach mit setTransferHandler an das JLabel.
Mit einem MouseListener kannst Du dann das automatische Drag Handling aktivieren, und zwar so:
Java:
MouseListener ml = new MouseAdapter() {
    public void mousePressed(MouseEvent e) {
        JComponent c = (JComponent)e.getSource();
        TransferHandler th = c.getTransferHandler();
        th.exportAsDrag(c, e, TransferHandler.COPY);
    }
};
label.addMouseListener(ml);

Im TransferHandler überschreibst du createTransferable um den Transferable
mit dem Wert aus dem JLabel zu erzeugen und zurückzugeben. Dann überschreibst du importData um die Übetragung der Daten zur Zielkomponente zu implementieren.
Und du überschreibst getSourceActions um die gültigen Aktionen zurückzugeben
(z.B.: return TransferHandler.COPY).
Du kannst auch exportDone überschreiben, um bei MOVE den JLabel Text zu löschen.

Ein universell einsetzbarer Transferable sieht so aus:

Java:
/************************
 * GenericTransferable  *
 ************************/
class GenericTransferable implements Transferable {
    private Object data;
    private static final DataFlavor[] flavors = new DataFlavor[1];
    static {flavors[0] = DataFlavor.stringFlavor;}
    public GenericTransferable(final Object data) {
        super();
        this.data = data;
    }
    public DataFlavor[] getTransferDataFlavors() {return flavors;}
    public boolean isDataFlavorSupported(final DataFlavor flavor) {return true;}
    public Object getTransferData(final DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        return data;
    }
}
Der stringFlavor ist hier nur der Form halber angegeben. Wenn TransferHandler#canImport immer true zurückgibt, spielt der DataFlavor keine Rolle und ich benutze auch keinen. Gewöhnlich genügt der Datentyp zur Steuerung der Verarbeitung.

Ich hoffe, das hilft dir schon etwas weiter.

Gruß,
André
 

Milgo

Mitglied
Super, das hat mir schon gut weitergeholfen. :) Ich kann jetzt schon verschiedene meiner Labels miteinander behandeln, dabei ist aber ein 'interessantes' Problem aufgetreten.

Erstmal mein wichtigster Code.
Java:
public class UnitLabel extends JLabel implements Transferable {
	[...]
	@Override
	public boolean isDataFlavorSupported(DataFlavor flavor) {
		return true;
	}

	@Override
	public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
		return this;
	}
}

class UnitTransferHandler extends TransferHandler {
	@Override
	public int getSourceActions(JComponent c) {
		if (c instanceof UnitLabel) {
			return LINK;
		}
		return NONE;
	}
	
	@Override
	public boolean importData(JComponent comp, Transferable t) {
		try {
			UnitLabel self = (UnitLabel) comp;
			UnitLabel other = (UnitLabel) t.getTransferData(DataFlavor.stringFlavor);
			
			if (!self.equals(other)) {
				// do stuff
				return true;
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	@Override
	public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
		if (comp instanceof UnitLabel) {
			return true;
		}
		return false;
	}
	
	@Override
	public Transferable createTransferable(JComponent c) {
		UnitLabel l = (UnitLabel) c;
		return l;
	}
}
Das beste Beispiel für mein Problem ist es, wenn ich eines der Labels auf sich selbst ziehe. In canImport() müssten die Objekte self und other eigentlich exakt gleich sein, sind sie aber nicht. Die Inhalte sind gleich aber nicht identisch, das heißt, dass wohl irgendwo das Ursprungsobjekt geklont wurde.

if (!self.equals(other)) packt dadurch beispielsweise nicht. Für mich ist es aber wichtig, dass die beiden Objekte auch genau die sind, die ich bearbeiten möchte und keine geklonten. Klar, das equals kann ich im Zweifelsfall anders umsetzen, aber für meine restlichen Arbeiten brauche ich die richtigen Objekte.

Gibts da irgendeinen Kniff den ich anwenden kann?
 

André Uhres

Top Contributor
if (!self.equals(other)) packt dadurch beispielsweise nicht. Für mich ist es aber wichtig, dass die beiden Objekte auch genau die sind, die ich bearbeiten möchte und keine geklonten.

Ich bezweifle, dass im vorliegenden Fall etwas geklont wurde. Spontan denke ich, dass es nur an der Umsetzung der "equals"-Methode liegen muss. Daher glaube ich, dass folgender Code in Deinem Beispiel funktionieren müsste:
Java:
if (self != other) {
    // do stuff
    return true;
}

Gruß,
André
 

André Uhres

Top Contributor
Das Problem kommt daher, dass das Objekt bei "getTransferData" durch einen Proxy serialisiert wird. Um diese Serialisierung zu verhindern, kann man so was machen:
Java:
DataFlavor dataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" +JComponent.class.getName(), "Class Description");
//This will avoid serializing the object and just refer to the object in the local jvm.
UnitLabel other = (UnitLabel) t.getTransferData(dataFlavor);

Also hier den DataFlavor "javaJVMLocalObjectMimeType" angeben, das verhindert die Serialisierung.
Ich hoffe, das hilft.

Gruß,
André
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Drag und drop aus einer JTable - bitte um Unterstützung AWT, Swing, JavaFX & SWT 2
G JPanel per Drag and Drop JButtons und Bilder ablegen AWT, Swing, JavaFX & SWT 1
AmsananKING ListView Drag And Drop AWT, Swing, JavaFX & SWT 0
AmsananKING Drag And Drop Filenames Inside A Listview AWT, Swing, JavaFX & SWT 1
DonBronson Java Graphics bewegbar machen (Drag&Drop) AWT, Swing, JavaFX & SWT 3
M Polygon per Drag&Drop verschieben AWT, Swing, JavaFX & SWT 26
Z Swing Drag and Drop mit einem JButton AWT, Swing, JavaFX & SWT 1
N Drag and Drop Fenster AWT, Swing, JavaFX & SWT 11
F Drag&Drop mit Transparenter Farbe bei PNG AWT, Swing, JavaFX & SWT 0
D JavaFX Pane per Drag&Drop bewegen? AWT, Swing, JavaFX & SWT 2
L JavaFX Drag and Drop funktioniert nicht AWT, Swing, JavaFX & SWT 3
J Drag and Drop von eigenen Objekten AWT, Swing, JavaFX & SWT 3
J Drag and Drop eines Buttons AWT, Swing, JavaFX & SWT 0
T Swing Drag and Drop für JComponents AWT, Swing, JavaFX & SWT 1
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
F Drag und Drop AWT, Swing, JavaFX & SWT 0
L JavaFX JavaFX Chart Drag and Drop AWT, Swing, JavaFX & SWT 3
D JavaFX Drag&Drop mehrerer TreeViews oder TableViews AWT, Swing, JavaFX & SWT 1
P Drag & Drop zwischen Panels AWT, Swing, JavaFX & SWT 0
U Drag and Drop mit imageview AWT, Swing, JavaFX & SWT 0
U Drag and Drop imageviews AWT, Swing, JavaFX & SWT 8
D SteelSeries in Netbeans als Drag-and-Drop einbinden AWT, Swing, JavaFX & SWT 0
C JTable Drag and Drop von Zeilen innerhalb einer Table AWT, Swing, JavaFX & SWT 2
S Swing Update eine JTabelle nach einer Drag&Drop Operation AWT, Swing, JavaFX & SWT 0
S Swing Suche Drag & Drop Beispiele AWT, Swing, JavaFX & SWT 1
A Drag and Drop mit JAVAFX- Scenebuilder AWT, Swing, JavaFX & SWT 1
R Performance Drag and Drop & Timer AWT, Swing, JavaFX & SWT 3
R Drag and Drop Problem auf Jpanel AWT, Swing, JavaFX & SWT 2
N Swing JTable und Drag und Drop AWT, Swing, JavaFX & SWT 2
A Drag and Drop eigener Objekte AWT, Swing, JavaFX & SWT 7
C Drag and Drop (inventar) AWT, Swing, JavaFX & SWT 15
F Swing Drag and Drop in JTree aus verschiedenen Listen AWT, Swing, JavaFX & SWT 6
T Swing JButton per Drag&Drop verschieben AWT, Swing, JavaFX & SWT 5
Iron Monkey JFileChooser - Drag and Drop AWT, Swing, JavaFX & SWT 5
Iron Monkey Nach Drag & Drop die Datei auf Komponent darstellen AWT, Swing, JavaFX & SWT 2
HaukeG Swing Drag & Drop in verschiedenen Varianten AWT, Swing, JavaFX & SWT 4
S Swing Drag&Drop mit TransferHandler und JPanels AWT, Swing, JavaFX & SWT 8
C Swing Simulation von Drag and Drop Events AWT, Swing, JavaFX & SWT 3
H Swing "Drag and Drop" eines JComponent über ein JPanel AWT, Swing, JavaFX & SWT 2
R Drag 'n Drop AWT, Swing, JavaFX & SWT 3
S Selektion bei Drag&Drop AWT, Swing, JavaFX & SWT 4
C Swing Drag and Drop mit Objekten in einem Fenster. AWT, Swing, JavaFX & SWT 9
T SWT Drag&Drop: Eclipse FileTransfer mit Icons AWT, Swing, JavaFX & SWT 14
F Drag & Drop durch Verbindungslinien AWT, Swing, JavaFX & SWT 10
T Swing Drag and Drop - JLabels tauschen statt überschreiben AWT, Swing, JavaFX & SWT 11
S Drag and Drop über 2 Panels AWT, Swing, JavaFX & SWT 2
K JButtons innerhalb eines JPanels verschieben (DRAG&DROP) AWT, Swing, JavaFX & SWT 5
B Drag and Drop AWT, Swing, JavaFX & SWT 6
K Drag and Drop Workbench AWT, Swing, JavaFX & SWT 2
P SWT Eclipse Draw2D Drag and Drop (ruckelt) AWT, Swing, JavaFX & SWT 4
F SWT Drag and Drop im TreeViewer AWT, Swing, JavaFX & SWT 4
B Swing Drag&Drop mit Feedback (Image am Mauszeiger) AWT, Swing, JavaFX & SWT 7
Spin JFrame/ Frame Drag and Drop AWT, Swing, JavaFX & SWT 13
A TransferHandler & Drag n' Drop AWT, Swing, JavaFX & SWT 2
R Drag an Drop JTable Zelle AWT, Swing, JavaFX & SWT 6
D Drag & Drop - node.isRoot AWT, Swing, JavaFX & SWT 3
E Swing Drag n Drop Verschieben von Labels o.ä. AWT, Swing, JavaFX & SWT 10
E Swing Beim Drag & Drop, Drag verbieten?! AWT, Swing, JavaFX & SWT 2
E JTree Autoscroll bei Drag and Drop AWT, Swing, JavaFX & SWT 4
F Swing Problem mit Drag&Drop in JTable AWT, Swing, JavaFX & SWT 4
C keine weiteren Events während Drag&Drop Operation möglich? AWT, Swing, JavaFX & SWT 5
E Drag&Drop zwischen 2 Listen AWT, Swing, JavaFX & SWT 5
0 Swing Drag n' Drop Bug wenn Source und Target gleiche Komponente? AWT, Swing, JavaFX & SWT 4
C Drag and Drop JPanel auf JPanel nach drop erneut verschieben? AWT, Swing, JavaFX & SWT 3
M Swing JTable Drag'n'Drop von Dateien AWT, Swing, JavaFX & SWT 3
M Drag and Drop: Quellfenster AWT, Swing, JavaFX & SWT 2
M Buttons per Drag & Drop im GridBagLayout verschieben AWT, Swing, JavaFX & SWT 6
M Swing JList > Drag & Drop AWT, Swing, JavaFX & SWT 2
C Drag an Drop vom JTree zur JTable AWT, Swing, JavaFX & SWT 4
Z Drag and Drop auf Application AWT, Swing, JavaFX & SWT 3
G Drag and Drop JTree to Canvas AWT, Swing, JavaFX & SWT 7
H Drag&Drop von JComponents AWT, Swing, JavaFX & SWT 6
G JTable drag and drop AWT, Swing, JavaFX & SWT 4
H Drag&Drop mit GWT AWT, Swing, JavaFX & SWT 8
B Swing Drag&Drop einzelner Zellen in einer JTable AWT, Swing, JavaFX & SWT 12
A Swing Drag and Drop TreeNode User Object AWT, Swing, JavaFX & SWT 3
P JList: Reihenfolge der Elemente per Drag'n'Drop ändern. AWT, Swing, JavaFX & SWT 9
K Swing Wie ändere ich die default action für Drag&Drop AWT, Swing, JavaFX & SWT 6
R JLayeredPane - Drag&Drop - mouseDragged AWT, Swing, JavaFX & SWT 6
C JTable mit RowSorter und Drag & Drop: Zeile verschieben AWT, Swing, JavaFX & SWT 4
V SWT TreeViewer Drag'n'Drop LocalSelectionTransfer AWT, Swing, JavaFX & SWT 10
R Swing JLayeredPane - Drag&Drop Positionen vertauschen AWT, Swing, JavaFX & SWT 3
F Drag & Drop mit eigenen Komponenten AWT, Swing, JavaFX & SWT 2
B SWT - Drag & Drop innerhalb einer Table AWT, Swing, JavaFX & SWT 3
S Drag'n'Drop AWT, Swing, JavaFX & SWT 8
E Drag&Drop JTable; Renderer füllt alle Zellen AWT, Swing, JavaFX & SWT 10
M Drag & Drop in Swing (createTransferable) AWT, Swing, JavaFX & SWT 6
T Drag Quelle beim Drop AWT, Swing, JavaFX & SWT 6
A Drag & Drop von Zeilen innerhalb einer Tabelle AWT, Swing, JavaFX & SWT 2
E Drag & Drop von jTree in JList AWT, Swing, JavaFX & SWT 5
P Dateien per Drag&Drop ins Java-Fenster ziehen AWT, Swing, JavaFX & SWT 8
G JTree Node ggf. aufklappen bei Drag & Drop? AWT, Swing, JavaFX & SWT 7
J Drag'n Drop imm selben Frame unterbinden AWT, Swing, JavaFX & SWT 3
S Table Row per Drag and Drop in andere Table schieben? AWT, Swing, JavaFX & SWT 14
X wiedermal Drag n Drop AWT, Swing, JavaFX & SWT 2
P Drag & Drop AWT, Swing, JavaFX & SWT 2
X Drag and Drop AWT, Swing, JavaFX & SWT 2
F Drag&Drop Jlist -> JList AWT, Swing, JavaFX & SWT 3
G Drag and Drop mal wieder? AWT, Swing, JavaFX & SWT 2
G Drag And Drop von Component (List, Tree) zum Desktop AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben