繁体   English   中英

带有自定义DataFormat的JavaFX DragAndDrop

[英]JavaFX DragAndDrop with custom DataFormat

概述

我正在Java FX应用程序中设置拖放功能。 当我尝试从Dragboard获取自定义数据时,我得到一个java.nio.HeapByteBuffer而不是Object作为JavaDoc stuggest。 此字节缓冲区不能转换到我的原始数据类型。

我在Scala工作,所以语法有点不同,但你明白了。 但是,也许是因为我在Scala中我得到了这个HeapByteBuffer而不是常规Object

细节

好的,这里我将创建可以拖放的JavaFX控件。 我要附加一个String和一个MyObject ; 可以检索StringMyObject则不能。
注意,我知道有更简单的方法将简单字符串附加到dragboard,这只是一个示例,表明MyObject应该可以从dragboard中检索。

在这里,我创建了一个可以拖动的自定义组件。 拖动时,两个对象附​​加到拖动板: MyObjectString

class ToolboxItem
    extends Label {

    setOnDragDetected(new EventHandler[MouseEvent] {
        def handle(event: MouseEvent) {
        val dragboard = startDragAndDrop(TransferMode.COPY)
        val content = new ClipboardContent()
        content.put(DnDTarget.DndString, "sean is cool")
        content.put(DnDTarget.DndObject, new MyObject)
        dragboard.setContent(content)
        event.consume()
    }

}

为了开始, MyObject非常简单:

class MyObject
    extends Serilaizable

现在,当我收到拖动事件时,我想从事件中获取此数据。
(另外,这里我定义了我的DataFormat

object DnDTarget {

    val DndString = new DataFormat("my.custom.dnd.string")
    val DndObject = new DataFormat("my.custom.dnd.object")

}

trait DnDTarget
    extends Node {

    setOnDragOver(new EventHandler[DragEvent]() {
        def handle(event: DragEvent) {
            if (valid(event)) {
                val dragboard = event.getDragboard
                val myString = dragboard.getContent(DnDTarget.DndString)
                val myObject = dragboard.getContent(DnDTarget.DndObject)
                myString.asInstanceOf[String]   // no problem
                myObject.asInstanceOf[MyObject] // throws exception
                event.acceptTransferModes(TransferMode.COPY)
            }
            event.consume()
        }
    })
}

好的,所以,调用myString.asInstanceOf[String]工作正常,我收回了我的String 但是, myObject.asInstanceOf[MyObject]抛出ClassCastException

线程“JavaFX Application Thread”中的异常java.lang.ClassCastException:java.nio.HeapByteBuffer无法强制转换为com.example.MyObject

注意:我不是在这里使用ScalaFX,在Scala中使用vanilla JavaFX

我在尝试在JavaFX 8中实现拖放时遇到了类似的问题。在实现自定义类型时,我在反序列化期间遇到了相同的异常。 我最终弄清楚了我的问题是什么。

这是我的错误,我的“MyObject”类实际上不可反序列化(因为它扩展了一个没有实现Serializable的超类型,并且没有默认的无参数构造函数,它必须具有这样的案件)。 无论如何,在测试“MyObject”可以在单元测试中被序列化/反序列化后,我的JavaFX拖放开始工作。 据我所知,问题是:

JavaFX错误处理似乎在反序列化期间隐藏任何​​异常,并返回序列化的bytebuffer而不是反序列化的对象。

这是有争议的,这是很好的错误处理。

在您的情况下,您可以尝试使用以下java代码自行反序列化从JavaFX获得的bytebuffer来测试:

public static MyObject deserialize(ByteBuffer buffer) {
    try {
        ByteArrayInputStream is = new ByteArrayInputStream(buffer.array());
        ObjectInputStream ois = new ObjectInputStream(is);
        MyObject obj = (MyObject) ois.readObject();
        return obj;
    } catch (IOException | ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

如果此方法抛出异常,则表明您有错误。 修复它,拖放应该再次开始工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM