TreeTableView拖放

kar*_*nbo 2 drag-and-drop javafx

我正在使用TreeTableView来显示树的内容.树中的排序顺序是手动的,我希望能够拖放项目.

如何在TreeTableView中拖放项目?

kar*_*nbo 6

一种方法是给我们一个'treeTableView.setRowFactory'.在'call'方法中,您创建了一个行,您可以在其上附加'onDragDetected','onDragDropped'等.请参阅下面的示例.

// Create the root, RowContainer is your class contianing row attributes
TreeItem<RowContainer> rootTIFX = new TreeItem<RowContainer>(rowContainerRoot);

// Add leaves under your root.
...

// Create the row factory
treeTableView.setRowFactory(new Callback<TreeTableView, TreeTableRow<RowContainer>>() {
    @Override
    public TreeTableRow<RowContainer> call(final TreeTableView param) {
        final TreeTableRow<RowContainer> row = new TreeTableRow<RowContainer>();

        row.setOnDragDetected(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                // drag was detected, start drag-and-drop gesture
                TreeItem<RowContainer> selected = (TreeItem<RowContainer>) treeTableView.getSelectionModel().getSelectedItem();
                // to access your RowContainer use 'selected.getValue()'

                if (selected != null) {
                    Dragboard db = treeTableView.startDragAndDrop(TransferMode.ANY);

                    // create a miniature of the row you're dragging
                    db.setDragView(row.snapshot(null, null));

                    // Keep whats being dragged on the clipboard
                    ClipboardContent content = new ClipboardContent();
                    content.putString(selected.getValue().getName());
                    db.setContent(content);

                    event.consume();
                }
            }
        });
        row.setOnDragOver(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
                // data is dragged over the target
                Dragboard db = event.getDragboard();
                if (event.getDragboard().hasString()){
                    event.acceptTransferModes(TransferMode.MOVE);
                }
                event.consume();
            }});
        row.setOnDragDropped(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {

                Dragboard db = event.getDragboard();
                boolean success = false;
                if (event.getDragboard().hasString()) {

                    if (!row.isEmpty()) {
                        // This is were you do your magic.
                        // Move your row in the tree etc 
                        // Here is two examples of how to access
                        // the drop destination:
                        int dropIndex = row.getIndex();
                        TreeItem<RowContainer> droppedon = row.getTreeItem();

                        success = true;
                    }
                }
                event.setDropCompleted(success);
                event.consume();
            }});
        return row;
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 使用行工厂是正确的,但有一些警告,如防止树中的循环和实现在treetableview中向上/向下滚动的机制.这里有完整的例子:http://programmingtipsandtraps.blogspot.co.at/2015/10/drag-and-drop-in-treetableview-with.html (2认同)