从一个 JavaFX 应用程序拖放到另一个

dragging and dropping from one JavaFX Application to another

我正在尝试通过拖放将一个元素从一个 JavaFX 应用程序移动到另一个应用程序,据我所知这应该不是问题。

所以我有一个 class 对象并将它从一个应用程序拖到另一个应用程序,然后将其内容打印到控制台。它大部分看起来不错,我可以通过尝试传输模式来降低到 "accepted" 或 "not accepted",这表明该机制本身似乎在工作。 但是当我将对象放在另一个应用程序上时,我认为大部分是中文,字母会打印到控制台。这显然是一些编码问题,但我无法真正弄清楚发生了什么,除了两个应用程序主要使用相同的代码库这一事实外, "chinese" 字母非常多。该对象的 toString 只打印了一行半的拉丁字符,但在放下时会打印出几段 "chinese" 个字母。

谁能告诉我这里发生了什么?它只是一个简单的编码 f-up 吗? OS (Win7 btw) 可能会干扰这里吗?我是否发现了久违的中国古代智慧?

代码本身相当简单,这里是来自"sender"

的代码
setOnDragDetected(event ->
            {
                Dragboard db = startDragAndDrop(TransferMode.ANY);

                ClipboardContent clipboardContent = new ClipboardContent();
                clipboardContent.put(DataFormat.PLAIN_TEXT, treeElement.getEntities());

                db.setContent(clipboardContent);

                System.out.println(db.getContent(DataFormat.PLAIN_TEXT));

                event.consume();
            });

这里来自 "receiver"

setOnDragDropped(event ->
    {
        Dragboard db = event.getDragboard();
        if (db.hasContent(DataFormat.PLAIN_TEXT))
        {
            System.out.println(db.getContent(DataFormat.PLAIN_TEXT));
            System.out.println("Accept Drop");
        }

        event.consume();
    });

我真的没有看到任何可以解释我的错误的东西。

问题是使用 DataFormat.PLAIN_TEXT。这意味着 JavaFX 认为数据格式就是它在罐头上所说的:文本,即 String 数据。事实并非如此。 DataFormat中没有static成员引用合适的DataFormat,需要自己创建一个:

final String mimeType = "application/javafx-entrylist"; // TODO: choose properly

// use existing format or introduce new one
DataFormat f = DataFormat.lookupMimeType(mimeType);
final DataFormat format = f == null ? new DataFormat(mimeType) : f;

setOnDragDetected(event -> {
    Dragboard db = startDragAndDrop(TransferMode.ANY);

    ClipboardContent clipboardContent = new ClipboardContent();
    clipboardContent.put(format, treeElement.getEntities());

    db.setContent(clipboardContent);

    System.out.println(db.getContent(format));

    event.consume();
});

setOnDragDropped(event -> {
    Dragboard db = event.getDragboard();
    if (db.hasContent(format)) {
        System.out.println(db.getContent(format));
        System.out.println("Accept Drop");
    }

    event.consume();
});