Javafx拖放第一次不起作用

标签 java javafx drag-and-drop

我刚刚制作了一个简单的应用程序,其中包括 FlowPane 和一些带有按钮的 VBox。

Main类是这样的。

public class Main extends Application {

    @Override
    public void start(Stage stage) {
        Gallery a = new Gallery();
        a.setMaxWidth(200);
        a.setPrefWidth(200);
        Scene scene = new Scene(a); 

        stage.setTitle("Welcome to JavaFX!"); 
        stage.setScene(scene); 
        stage.sizeToScene(); 
        stage.show(); 
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这个 Gallery.class 是扩展 FlowPane 的主要背景类。

public class Gallery extends FlowPane{

    public Gallery() {
        super();

        PlotterPanel p1 = new PlotterPanel(this, "B1" );
        getChildren().add(p1);

        PlotterPanel p2 = new PlotterPanel(this, "B2");
        getChildren().add(p2);

        PlotterPanel p3 = new PlotterPanel(this, "B3" );
        getChildren().add(p3);

        PlotterPanel p4 = new PlotterPanel(this, "B4" );
        getChildren().add(p4);

        PlotterPanel p5 = new PlotterPanel(this, "B5" );
        getChildren().add(p5);

        PlotterPanel p6 = new PlotterPanel(this, "B6" );
        getChildren().add(p6);


    }
}

PlotterPanel是VBox,有Button,可以在Gallery中拖放。


public class PlotterPanel extends VBox{

    private static final String TAB_DRAG_KEY = "titledpane";
    private ObjectProperty<VBox> draggingTab;
    private Gallery mgallery;
    private PlotterPanel self;

    public PlotterPanel(Gallery gallery, String name) {
        super();
        mgallery = gallery;
        setPrefWidth(100);
        setPrefHeight(100);
        self = this;

        Button btn = new Button(name);
        btn.setEffect(new DropShadow());
        getChildren().add(btn);

        draggingTab = new SimpleObjectProperty<VBox>();

        setOnDragOver(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
                final Dragboard dragboard = event.getDragboard();
                if (dragboard.hasString()
                        && TAB_DRAG_KEY.equals(dragboard.getString())
                        && draggingTab.get() != null) {
                    event.acceptTransferModes(TransferMode.MOVE);
                    event.consume();
                }
            }
        });
        setOnDragDropped(new EventHandler<DragEvent>() {
            public void handle(final DragEvent event) {
                Dragboard db = event.getDragboard();
                boolean success = false;
                if (db.hasString()) {
                    Pane parent = mgallery;
                    Object source = event.getGestureSource();
                    int sourceIndex = parent.getChildren().indexOf(source);
                    System.out.println(sourceIndex);
                    int targetIndex = parent.getChildren().indexOf(self);
                    System.out.println(targetIndex);
                    List<Node> nodes = new ArrayList<Node>(parent.getChildren());
                    if (sourceIndex < targetIndex) {
                        Collections.rotate(
                                nodes.subList(sourceIndex, targetIndex + 1), -1);
                    } else {
                        Collections.rotate(
                                nodes.subList(targetIndex, sourceIndex + 1), 1);
                    }
                    parent.getChildren().clear();
                    parent.getChildren().addAll(nodes);
                    success = true;
                }
                event.setDropCompleted(success);
                event.consume();
            }
        });
        setOnDragDetected(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                Dragboard dragboard = self.startDragAndDrop(TransferMode.MOVE);
                ClipboardContent clipboardContent = new ClipboardContent();
                clipboardContent.putString(TAB_DRAG_KEY);
                dragboard.setContent(clipboardContent);
                draggingTab.set(self);
                event.consume();
            }
        }); 
    }

}

问题是,当我在 Gallery 中拖动 PlotterPanel 时,第一次无法拖动它。我在第二次尝试后工作了。 当我开始拖动时,它显示拖动框,但是当我尝试放在另一个节点上时,鼠标点显示 x 符号。 但是当目标已经尝试过要拖动的节点时,我可以将其放在该节点上。

如何使拖放在 JavaFX 中正常工作?

最佳答案

问题在于您接受拖动的条件:

            if (dragboard.hasString()
                    && TAB_DRAG_KEY.equals(dragboard.getString())
                    && draggingTab.get() != null) {
                event.acceptTransferModes(TransferMode.MOVE);
                event.consume();
            }

您正在检查目标的draggingTab,而不是源。如果目标本身未被拖动,则其 draggingTab 属性仍将为 null。如果您已经拖动了目标,那么它不会为空并且它将接受拖动。

您的意思是使 draggingTab 静态吗?

关于Javafx拖放第一次不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57700207/

相关文章:

java - Apache 公共(public) Fileutils

java - 如何使用 JQuery 处理 Ajax http post 的成功和失败?

css - 隐藏 YUI 库中的调整大小句柄不起作用

java - spring-boot @Scheduled pool-size 调试

java - Hybris 服务器显示垃圾收集问题?

mysql - 警告消息不显示

java - 线程 "main"java.lang.NoSuchMethodException : after I add ArrayList 中的异常

java - 如何固定边框节点?

java - 如何在我自己的应用程序中获得拖动到 bin 的主屏幕行为?

c++ - Qt 站点示例