diff --git a/treedrag/DragAndScrollTreeView.java b/treedrag/DragAndScrollTreeView.java new file mode 100644 index 0000000..9c97342 --- /dev/null +++ b/treedrag/DragAndScrollTreeView.java @@ -0,0 +1,92 @@ +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; +import javafx.geometry.Orientation; +import javafx.scene.Node; +import javafx.scene.control.ScrollBar; +import javafx.scene.control.TreeItem; +import javafx.scene.control.TreeView; +import javafx.scene.input.DragEvent; +import javafx.scene.input.ScrollEvent; +import javafx.util.Duration; + +public class DragAndScrollTreeView extends TreeView { + + private Timeline scrollTimeline = new Timeline(); + private double scrollVelocity = 0; + private boolean dropped; + + // Higher SCROLL_SPEED value = slower scroll. + private static final int SCROLL_SPEED = 100; + private static final int SCROLL_DURATION = 20; + + + public DragAndScrollTreeView(TreeItem root) { + super(root); + + setupScrolling(); + } + + + private void setupScrolling () { + scrollTimeline.setCycleCount(Timeline.INDEFINITE); + scrollTimeline.getKeyFrames().add(new KeyFrame(Duration.millis(SCROLL_DURATION), (ActionEvent) -> dragScroll())); + + setOnDragExited((DragEvent event) -> { + + if (event.getY() > 0) { + scrollVelocity = 1.0 / SCROLL_SPEED; + } + else { + scrollVelocity = -1.0 / SCROLL_SPEED; + } + if (!dropped){ + scrollTimeline.play(); + } + + }); + + setOnDragEntered(event -> { + scrollTimeline.stop(); + dropped = false; + }); + + setOnDragDone(event -> { + scrollTimeline.stop(); + }); + + setOnDragDropped((DragEvent event) ->{ + scrollTimeline.stop(); + event.setDropCompleted(true); + dropped = true; + }); + + setOnScroll((ScrollEvent event)-> { + scrollTimeline.stop(); + }); + } + + + private void dragScroll () { + ScrollBar sb = getVerticalScrollbar(); + if (sb != null) { + double newValue = sb.getValue() + scrollVelocity; + newValue = Math.min(newValue, 1.0); + newValue = Math.max(newValue, 0.0); + sb.setValue(newValue); + } + } + + + private ScrollBar getVerticalScrollbar() { + ScrollBar result = null; + for (Node n : lookupAll(".scroll-bar")) { + if (n instanceof ScrollBar) { + ScrollBar bar = (ScrollBar) n; + if (bar.getOrientation().equals(Orientation.VERTICAL)) { + result = bar; + } + } + } + return result; + } +} diff --git a/treedrag/TaskCellFactory.java b/treedrag/TaskCellFactory.java index d90dd96..b23d6a2 100644 --- a/treedrag/TaskCellFactory.java +++ b/treedrag/TaskCellFactory.java @@ -29,7 +29,7 @@ public TreeCell call(TreeView treeView) { @Override protected void updateItem(TaskNode item, boolean empty) { super.updateItem(item, empty); - if (item == null) return; + if (item == null || empty) return; ImageView iv1 = new ImageView(); if (item.getName().equals("Tasks")) { @@ -86,7 +86,7 @@ private void dragOver(DragEvent event, TreeCell treeCell, TreeView treeCell, TreeView treeView) { Dragboard db = event.getDragboard(); - boolean success = false; + event.setDropCompleted(false); if (!db.hasContent(JAVA_FORMAT)) return; TreeItem thisItem = treeCell.getTreeItem(); @@ -106,7 +106,7 @@ private void drop(DragEvent event, TreeCell treeCell, TreeView(new TaskNode("walk dog"))); children.add(new TreeItem(new TaskNode("buy beer"))); - TreeView tree = new TreeView(rootItem); + DragAndScrollTreeView tree = new DragAndScrollTreeView(rootItem); tree.setCellFactory(new TaskCellFactory()); StackPane root = new StackPane();