我正在设置拖拽和放大器放入Java FX应用程序。当我尝试从Dragboard
获取自定义数据时,我得到java.nio.HeapByteBuffer
而不是Object
作为JavaDoc stuggest。此字节缓冲区不能强制转换到我的原始数据类型。
我在Scala工作所以它的语法有点不同但你明白了。但是,也许是因为我在Scala中我得到了HeapByteBuffer
而不是常规的Object
?
好的,这里我要创建可以拖放的JavaFX控件。我要附上String
和MyObject
; String
无法检索到MyObject
注意,我知道有更简单的方法将简单字符串附加到dragboard,这只是一个示例,表明MyObject
也应该可以从dragboard中检索。
这里我创建了一个可以拖动的自定义组件。
拖动时,拖动板上会附加两个对象:MyObject
和String
。
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
答案 0 :(得分:2)
我遇到了类似的问题,同时尝试在JavaFX 8中实现拖放。在实现自定义类型时,我在反序列化期间遇到了相同的异常。我最终弄清楚了我的问题是什么。
这是我的一个错误,我的" MyObject" class实际上不能反序列化(因为它扩展了一个没有实现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);
}
}
如果此方法抛出异常,则表明您有错误。修复它,拖放应该再次开始工作。