TornadoFX 在 TreeView 上拖放
TornadoFX Drag and Drop on a TreeView
我是 JavaFX 的新手,因此也是 TornadoFX 的新手,所以请多多包涵。
我在 Java 中有一个简单的应用程序,但想将其移至 Kotlin,并且 运行 遇到了在 TornadoFX 中寻找相应机制的问题。我有一个 ListView
持有 IStoryItem
的实现,代表故事和章节。我希望能够移动章节,甚至从一个故事移动到另一个故事。 Java 中的 TreeView
在其 setCellFactory
调用中具有以下实现:
tv.setCellFactory(new Callback<TreeView<IStoryItem>, TreeCell<IStoryItem>>() {
@Override
public TreeCell<IStoryItem> call(TreeView<IStoryItem> siTreeView) {
TreeCell<IStoryItem> cell = new TreeCellStoryEditor();
cell.setOnDragDetected((MouseEvent event) -> {
// Don't drag Story nodes.
if (cell.getItem() instanceof Story) return;
Dragboard db = cell.startDragAndDrop(TransferMode.MOVE);
// Put the Part on the dragboard
// From:
ClipboardContent content = new ClipboardContent();
content.put(objectDataFormat, cell.getItem());
db.setContent(content);
event.consume();
});
cell.setOnDragOver((DragEvent event) -> {
if (event.getGestureSource() != cell && event.getDragboard().hasContent(objectDataFormat)) {
/* allow for moving */
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
});
cell.setOnDragEntered((DragEvent event) -> {
IStoryItem item = cell.getItem();
if (item instanceof Story &&
event.getGestureSource() != cell &&
event.getDragboard().hasContent(objectDataFormat)) {
cell.setUnderline(true);
}
event.consume();
});
cell.setOnDragExited((DragEvent event) -> {
cell.setUnderline(false);
event.consume();
});
cell.setOnDragDropped((DragEvent event) -> {
try {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasContent(objectDataFormat)) {
Part droppedPart = (Part)db.getContent(objectDataFormat);
IStoryItem targetStoryItem = cell.getItem();
// Question: How to handle drops between leaf items or
// before the initial leaf or after the final leaf.
if (targetStoryItem instanceof Story) {
Story story = (Story) targetStoryItem;
updateStoryWith(droppedPart, story);
addPartTo(cell.getTreeItem(), droppedPart);
success = true;
}
}
event.setDropCompleted(success);
event.consume();
} catch (Exception e) {
System.out.println(e.getMessage());
}
});
cell.setOnDragDone((DragEvent event) -> {
if (event.getTransferMode() == TransferMode.MOVE) {
IStoryItem item = cell.getItem();
TreeItem<IStoryItem> ti = cell.getTreeItem();
TreeItem<IStoryItem> pti = ti.getParent();
pti.getChildren().remove(ti);
IStoryItem psi = pti.getValue();
// Remove the Part/Chapter from its previous Story
boolean removed = removePartFrom(psi, item);
}
event.consume();
});
cell.setEditable(true);
return cell;
};
});
我在 TornadoFX 中寻找过类似的东西,但找不到任何看起来可行的东西。我已经在使用 cellFormat
生成器,但我不知道如何在其中添加事件处理程序。我从 IntelliJ 的智能感知中看到还有一个 cellFactory
构建器,但我不确定如何使用它或如何向它添加事件处理程序。
您可以在 TornadoFX 中使用完全相同的技术。请记住,TornadoFX 只是在 JavaFX 之上应用了一个高级 API。您始终可以毫无问题地访问底层 JavaFX API。
tv.setCellFactory {
object : TreeCell<IStoryItem>() {
init {
setOnDragOver { event ->
}
setOnDragEntered { event ->
}
setOnDragExited { event ->
}
setOnDragDropped { event ->
}
}
}
}
我是 JavaFX 的新手,因此也是 TornadoFX 的新手,所以请多多包涵。
我在 Java 中有一个简单的应用程序,但想将其移至 Kotlin,并且 运行 遇到了在 TornadoFX 中寻找相应机制的问题。我有一个 ListView
持有 IStoryItem
的实现,代表故事和章节。我希望能够移动章节,甚至从一个故事移动到另一个故事。 Java 中的 TreeView
在其 setCellFactory
调用中具有以下实现:
tv.setCellFactory(new Callback<TreeView<IStoryItem>, TreeCell<IStoryItem>>() {
@Override
public TreeCell<IStoryItem> call(TreeView<IStoryItem> siTreeView) {
TreeCell<IStoryItem> cell = new TreeCellStoryEditor();
cell.setOnDragDetected((MouseEvent event) -> {
// Don't drag Story nodes.
if (cell.getItem() instanceof Story) return;
Dragboard db = cell.startDragAndDrop(TransferMode.MOVE);
// Put the Part on the dragboard
// From:
ClipboardContent content = new ClipboardContent();
content.put(objectDataFormat, cell.getItem());
db.setContent(content);
event.consume();
});
cell.setOnDragOver((DragEvent event) -> {
if (event.getGestureSource() != cell && event.getDragboard().hasContent(objectDataFormat)) {
/* allow for moving */
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
});
cell.setOnDragEntered((DragEvent event) -> {
IStoryItem item = cell.getItem();
if (item instanceof Story &&
event.getGestureSource() != cell &&
event.getDragboard().hasContent(objectDataFormat)) {
cell.setUnderline(true);
}
event.consume();
});
cell.setOnDragExited((DragEvent event) -> {
cell.setUnderline(false);
event.consume();
});
cell.setOnDragDropped((DragEvent event) -> {
try {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasContent(objectDataFormat)) {
Part droppedPart = (Part)db.getContent(objectDataFormat);
IStoryItem targetStoryItem = cell.getItem();
// Question: How to handle drops between leaf items or
// before the initial leaf or after the final leaf.
if (targetStoryItem instanceof Story) {
Story story = (Story) targetStoryItem;
updateStoryWith(droppedPart, story);
addPartTo(cell.getTreeItem(), droppedPart);
success = true;
}
}
event.setDropCompleted(success);
event.consume();
} catch (Exception e) {
System.out.println(e.getMessage());
}
});
cell.setOnDragDone((DragEvent event) -> {
if (event.getTransferMode() == TransferMode.MOVE) {
IStoryItem item = cell.getItem();
TreeItem<IStoryItem> ti = cell.getTreeItem();
TreeItem<IStoryItem> pti = ti.getParent();
pti.getChildren().remove(ti);
IStoryItem psi = pti.getValue();
// Remove the Part/Chapter from its previous Story
boolean removed = removePartFrom(psi, item);
}
event.consume();
});
cell.setEditable(true);
return cell;
};
});
我在 TornadoFX 中寻找过类似的东西,但找不到任何看起来可行的东西。我已经在使用 cellFormat
生成器,但我不知道如何在其中添加事件处理程序。我从 IntelliJ 的智能感知中看到还有一个 cellFactory
构建器,但我不确定如何使用它或如何向它添加事件处理程序。
您可以在 TornadoFX 中使用完全相同的技术。请记住,TornadoFX 只是在 JavaFX 之上应用了一个高级 API。您始终可以毫无问题地访问底层 JavaFX API。
tv.setCellFactory {
object : TreeCell<IStoryItem>() {
init {
setOnDragOver { event ->
}
setOnDragEntered { event ->
}
setOnDragExited { event ->
}
setOnDragDropped { event ->
}
}
}
}