Sea*_*lly 5 java bytebuffer drag-and-drop scala javafx
我正在 Java FX 应用程序中设置拖放。当我尝试从JavaDoc stuggest 中获取自定义数据时,Dragboard我得到了一个java.nio.HeapByteBuffer而不是一个Object。此字节缓冲区不能投给我的原始数据类型。
我在 Scala 工作,所以它的语法有点不同,但你明白了。但是,也许是因为我在 Scala 中才得到这个HeapByteBuffer而不是常规的Object?
好的,这里我将创建可以拖放的 JavaFX 控件。我要附上一个String和一个MyObject; 在String可以同时被检索MyObject不能。
请注意,我知道有更简单的方法可以将简单的字符串附加到拖动板上,这只是一个示例,表明它也MyObject应该可以从拖动板上检索。
在这里,我创建了一个可以拖动的自定义组件。拖动时,两个对象会附加到拖动板上:aMyObject和 a 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()
}
}
Run Code Online (Sandbox Code Playgroud)
MyObject 为了开始,非常简单:
class MyObject
extends Serilaizable
Run Code Online (Sandbox Code Playgroud)
现在,当我收到拖动事件时,我想从事件中获取这些数据。
(另外,这里我定义了我的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()
}
})
}
Run Code Online (Sandbox Code Playgroud)
好的,所以,通话myString.asInstanceOf[String]工作正常,我String回来了。然而,myObject.asInstanceOf[MyObject]抛出ClassCastException一句话:
线程“JavaFX 应用程序线程”中的异常 java.lang.ClassCastException:java.nio.HeapByteBuffer 无法转换为 com.example.MyObject
注意:我没有在这里使用 ScalaFX,在 Scala 中使用 vanilla JavaFX
我在尝试在 JavaFX 8 中实现拖放时遇到了类似的问题。在实现自定义类型时,我在反序列化期间遇到了相同的异常。我最终弄清楚了我的情况的问题所在。
这是我的一个错误,我的“MyObject”类实际上不可反序列化(在我的例子中,MyObject 扩展了一个没有实现 Serialized 的超类型,并且没有默认的无参数构造函数,它必须在这样的情况)。无论如何,在测试“MyObject”可以在单元测试中序列化/反序列化之后,我的 JavaFX 拖放开始工作。据我所知,问题是这样的:
JavaFX 错误处理似乎隐藏了反序列化期间的任何异常,并返回序列化的字节缓冲区而不是反序列化的对象。
这是否是良好的错误处理是有争议的。
在您的情况下,您可以通过尝试使用以下 java 代码自行反序列化从 JavaFX 获得的字节缓冲区来测试这一点:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果此方法抛出异常,则说明您有错误。修复它,拖放操作应该再次开始工作。