Java: verwenden der Zwischenablage zum kopieren und einfügen von java-Objekten zwischen verschiedenen Instanzen der gleichen Anwendung
Bin ich versucht zu implementieren, kopieren und einfügen von Objekten zwischen verschiedenen Instanzen der gleichen Anwendung. Derzeit funktioniert es nur in einer Anwendung (ich meine, kopieren und einfügen in der gleichen Instanz der Anwendung), aber nicht zwischen verschiedenen Instanzen.
Kopieren code:
//MyObject is a class of objects I want to copy/paste;
//MyObjectSelection is a class that impements Transferable and ClipboardOwner interfaces
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
MyObject data = new MyObject(selectedItems);
MyObjectSelection dataSelection = new MyObjectSelection(data);
clipboard.setContents(dataSelection, this);
Danach kann ich prüfen Sie den Inhalt der Zwischenablage, so:
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable clipboardContent = clipboard.getContents(this);
DataFlavor[] flavors = clipboardContent.getTransferDataFlavors();
System.out.println("flavors.length=" + flavors.length);
for (int i = 0; i < flavors.length; i++){
System.out.println("flavor=" + flavors[i]);
}
Wenn ich dies von der gleichen Instanz der Anwendung, dass ich das Objekt kopiert, es funktioniert: flavors.length
ist 1
, mimetype application/x-java-serialized-object
, und, gut, es funktioniert.
Aber wenn ich öffnen Sie die Anwendung, führen Sie "kopieren", dann öffnen Sie die gleiche Anwendung wieder (der erste ist nicht geschlossen, D. H. beide Instanzen gleichzeitig ausgeführt werden), und versuchen Sie, überprüfen Sie den Inhalt der Zwischenablage, von dort, dann flavors.length
ist 0
.
Untersuchte ich die Doku und die Beispiele an: ein, zwei, aber ich kann immer noch nicht finden, was falsch ist in meiner Implementierung.
Hab ich was verpasst?
UPD: ich Hinzugefügt sscce: clipboard_test.zip.
Diese test-Anwendung (ich benutze Eclipse um es zu bauen) mit 3 Quellcode-Dateien:
ClipboardTest.java
- main app KlasseMyObject.java
- Klasse für Objekte kopieren/einfügen (diese Klasse enthält nur array vonString
)-
MyObjectSelection.java
- Klasse, dieTranserable
undClipboardOwner
SchnittstellenGibt es zwei Schaltflächen: "kopieren", "test" stellen.
Wenn Sie die Taste "copy" - button, neue Instanz von MyObject erstellt
und setzen Sie in die Zwischenablage.Wenn Sie drücken Sie die Schaltfläche "test", den Inhalt der Zwischenablage geprüft werden
und auch für die Konsole (Anzahl der unterstütztenDataFlavor
's, und jederDataFlavor
)So, replizieren diese Schritte:
-
Anwendung starten
- Drücken Sie die "copy" - Taste: Sie sehen
"object copied"
Meldung in die log - -
Drücken Sie die "test" - Taste: Sie werden sehen, Zwischenablage Inhalt:
flavors.length = 1 flavor[0] = java.awt.datatransfer.DataFlavor[mimetype=application/x-java-serialized-object;representationclass=MyObject]
-
Starten Sie eine andere Instanz der Anwendung (schließen Sie nicht die erste)
-
Drücken Sie die "test" - Taste: Sie werden sehen, dass die Zwischenablage leer ist:
flavors.length = 0
Warum ist das so?
UPD2: sscce direkt gebucht hier:
import java.awt.BorderLayout;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
public final class ClipboardTest implements Runnable, ClipboardOwner {
public static void main(String[] args) {
SwingUtilities.invokeLater (new ClipboardTest());
}
public void run() {
JFrame f = new JFrame ("Clipboard test");
f.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
//-- Create "copy" button.
// When you click it, new object "test_items" becomes created
// and put to the clipboard.
{
JButton button_copy = new JButton("copy");
button_copy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String[] test_items = {
"one", "two", "three"
};
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
MyObject data = new MyObject(test_items);
MyObjectSelection dataSelection = new MyObjectSelection(data);
clipboard.setContents(dataSelection, ClipboardTest.this);
System.out.println("object copied");
}
});
f.add(button_copy, BorderLayout.NORTH);
}
//-- Create "test" button.
// When you click it, clipboard contents are checked
// and echoed to the console (count of supported DataFlavor's, and each DataFlavor)
{
JButton button_test = new JButton("test");
button_test.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable clipboardContent = clipboard.getContents(this);
DataFlavor[] flavors = clipboardContent.getTransferDataFlavors();
System.out.println("flavors.length = " + flavors.length);
for (int i = 0; i < flavors.length; i++){
System.out.println("flavor[" + i + "] = " + flavors[i]);
}
}
});
f.add(button_test, BorderLayout.SOUTH);
}
f.pack();
f.setVisible(true);
}
//ClipboardOwner implementation
@Override
public void lostOwnership(Clipboard clipboard, Transferable transferable){
System.out.println("ClipboardTest: Lost ownership");
}
/* *****************************************************************************************
* Object that I want to copy/paste
* ****************************************************************************************/
public static class MyObject {
private String[] items;
public MyObject(String[] items){
this.setItems(items);
}
public String[] getItems(){
return this.items;
}
public void setItems(String[] items){
this.items = items;
}
}
public static class MyObjectSelection implements Transferable, ClipboardOwner {
private static DataFlavor dmselFlavor = new DataFlavor(MyObject.class, "Test data flavor");
private MyObject selection;
public MyObjectSelection(MyObject selection){
this.selection = selection;
}
//Transferable implementation
@Override
public DataFlavor[] getTransferDataFlavors(){
System.out.println("getTransferDataFlavors");
DataFlavor[] ret = {dmselFlavor};
return ret;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor){
return dmselFlavor.equals(flavor);
}
@Override
public synchronized Object getTransferData (DataFlavor flavor)
throws UnsupportedFlavorException
{
if (isDataFlavorSupported(flavor)){
return this.selection;
} else {
throw new UnsupportedFlavorException(dmselFlavor);
}
}
//ClipboardOwner implementation
@Override
public void lostOwnership(Clipboard clipboard, Transferable transferable){
System.out.println("MyObjectSelection: Lost ownership");
}
}
}
- Für bessere Hilfe früher, nach einem SSCCE.
- Das Betriebssystem und die JVM Start-Argumente/ - Konfiguration auch eine Menge zu sagen über den Zugriff auf die Globale Zwischenablage
- Ich habe es, meine aktualisierte Frage.
- welches Betriebssystem / windowing-Umgebung sind verwenden Sie?
- Wenn die SSCCE ist kurz genug sind, um direkt zu dem forum, Mach das. Ich bin nicht das herunterladen eines Zip, um Ihnen zu helfen.
- getan.
- Windows XP, standard-explorer.
- "Importe sind weggelassen)" ich fühlen sich in der Regel die Importe müssen in einem SSCCE. Ein SSCCE auch sollte 1 Quell-Datei (auch wenn es mehrere Klassen innerhalb, einer source-Datei).
- getan.
- Jetzt dass ist ein SSCCE. ..Leider kann ich nicht für das Leben von mir, Abbildung, warum es nicht zu kopieren, auf der 2. Instanz.
- aber es ist schon gelöst, wie Sie sehen können: MvG richtige Antwort. Vielen Dank für den Unterricht mir über SSCCE =)
- Oh, cool. 😛 Froh, Sie haben es sortiert. 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zitieren dieses tutorial:
Ihre
MyObject
ist nichtSerializable
, so kann es nicht funktionieren. Der Rahmen anscheinend erkennt diese Tatsache (im Gegensatz zu einer situation mit einem unserializable serialisierbare Unterklasse einer übergeordneten Klasse, oder ähnliche Szenarien, in denen nicht-serialisierbarkeit erkannt wird nur in den Prozess), so dass es gar nicht mit, bieten, die den Geschmack zu anderen Prozessen.Im Allgemeinen zwei Instanzen der gleichen java-Anwendung nicht auf demselben Adressraum, so können Sie nicht einfach auf einen anderen Speicher. Daher alles, was Ihnen die übertragung serialisiert werden.
DataFlavor
Dokumentation: docs.oracle.com/javase/7/docs/api/java/awt/datatransfer/...