gpt4 book ai didi

Java:使用剪贴板在同一应用程序的不同实例之间复制粘贴 Java 对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:48:50 25 4
gpt4 key购买 nike

我正在尝试在同一应用程序的不同实例之间实现对象的复制粘贴。目前它仅适用于一个应用程序(我的意思是,在同一应用程序实例中复制和粘贴),但在不同实例之间不起作用。

复制代码:

// 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);

之后,我可以检查剪贴板的内容,像这样:

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]);
}

如果我从复制对象的同一应用程序实例执行此操作,它会工作:flavors.length1,mimetype 是 application/x-java -serialized-object,而且,它有效。

但是如果我打开应用程序,执行复制,然后再次打开同一个应用程序(第一个没有关闭,即两个实例同时运行),并尝试从那里检查剪贴板内容,然后 flavors.length 0

我检查了文档和这些示例:one , two ,但我仍然找不到我的实现有什么问题。

我错过了什么吗?


UPD: 我添加了 sscce:clipboard_test.zip .

这是带有 3 个源文件的测试应用程序(我使用 Eclipse 构建它):

  • ClipboardTest.java - 主应用类
  • MyObject.java - 用于复制/粘贴对象的类(此类仅包含 String 数组)
  • MyObjectSelection.java - 实现TranserableClipboardOwner 接口(interface)的类

    有两个按钮:“复制”、“测试”。

    当您按下“复制”按钮时,将创建 MyObject 的新实例并放入剪贴板。

    当您按下“测试”按钮时,将检查剪贴板内容并回显到控制台(支持的 DataFlavor 的计数,以及每个 DataFlavor)

    因此,重复这些步骤:

  • 开始申请

  • 按“复制”按钮:您将在日志中看到“对象已复制”消息
  • 按“测试”按钮:您将看到剪贴板的内容:

       flavors.length = 1
    flavor[0] = java.awt.datatransfer.DataFlavor[mimetype=application/x-java-serialized-object;representationclass=MyObject]
  • 启动应用程序的另一个实例(不要关闭第一个实例)

  • 按“测试”按钮:你会看到剪贴板是空的:

       flavors.length = 0

这是为什么?


UPD2: sscce 直接在此处发布:

  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");
}

}

}

最佳答案

引用 this tutorial :

Transferring the data using this mechanism uses Object serialization, so the class you use to transfer the data must implement the Serializable interface, as must anything that is serialized with it. If everything is not serializable, you will see a NotSerializableException during drop or copy to the clipboard.

您的 MyObject 不是 Serializable ,所以它不能工作。该框架显然检测到这一事实(与可序列化父类的不可序列化子类的情况相反,或仅在进程中检测到不可序列化的类似场景),因此它甚至不会向其他进程提供这种风格。

一般来说,同一个 java 应用程序的两个实例不会有相同的地址空间,因此它们不能简单地访问彼此的内存。因此,您传输的所有内容都必须序列化。

关于Java:使用剪贴板在同一应用程序的不同实例之间复制粘贴 Java 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14276182/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com