当前位置: 首页 > 知识库问答 >
问题:

JavaFX Dragboard setContent干扰SetonMouseDrag?

萧宏峻
2023-03-14

我想在JavaFX中使用拖放,并有一个功能,您可以直观地看到正在拖动的项目。我已经实现了我认为可行的解决方案,但API似乎存在问题。

根据API start DragAndDrop(TransferMode...)必须在setOnDragDetted中初始化。这是我使用Dragboard存储我想传输到另一个节点的内容的地方。

编辑:这似乎与TrasferMode有关。如果我使用TransferMode。没有问题,但是使用COPY、ANY、LINK总是会导致这个问题。

但是呼叫拖板。setContent(一些剪贴板内容)只允许鼠标移动非常小的增量(在任何方向上最多4个像素!)。删除这行代码后,我可以拖动该项目并看到它被拖动到任何地方,但当然,我无法存储剪贴板内容。

我看到的问题是setonmousedrable(..)在检测到setondrag之前被调用!为什么SetonMouseDrag在检测到setOnDragDetected之前运行,这没有多大意义。。。

我的代码中是否有明显的问题?我只是希望能够看到imgView在拖动时移动,并且能够像往常一样将其与剪贴板内容一起放置在目标上。

编辑2:更新了下面的代码,以反映仅使用拖动事件,而不是拖动和鼠标事件。使用这两个引起的问题。仍然存在的问题是我无法拖放目标,因为使用setOnDragover会使被拖动的节点始终位于光标下方。

protected ImageView initImageView(Image img){

    final Pane ldzPane = GameBoard.getInstance().getLDZpane();

    final ObjectProperty<Point2D> dragAnchor = new SimpleObjectProperty<>();

    final ImageView imgView = new ImageView(img);

    final DoubleProperty initX = new SimpleDoubleProperty();
    final DoubleProperty initY = new SimpleDoubleProperty();

    final DoubleProperty dragX = new SimpleDoubleProperty();
    final DoubleProperty dragY = new SimpleDoubleProperty();

    final DoubleProperty newXPosition = new SimpleDoubleProperty();
    final DoubleProperty newYPosition = new SimpleDoubleProperty();

    final int buffer = 3;

    imgView.setOnDragDetected(new EventHandler<MouseEvent>() {
        public void handle(MouseEvent event) {
            initX.set(imgView.getTranslateX());
            initY.set(imgView.getTranslateY());
            dragAnchor.set(new Point2D(event.getSceneX(), event.getSceneY()));
            ClipboardContent content = new ClipboardContent();
            content.putString(RHSIconizedToken.this.tokenLookupInfo());
            Dragboard db = imgView.startDragAndDrop(TransferMode.ANY); 
            db.setContent(content); 
            event.consume();
        }
    });

    imgView.setOnDragOver(new EventHandler<DragEvent>(){

        @Override
        public void handle(DragEvent event) {
            imgView.toFront();

            dragX.set(event.getSceneX() - dragAnchor.get().getX());
            dragY.set(event.getSceneY() - dragAnchor.get().getY());
            imgView.setOpacity(0.5);

            newXPosition.set(initX.get() + dragX.get());
            newYPosition.set(initY.get() + dragY.get());

            //if(       (Math.abs((newXPosition.get() - ldzPane.getWidth())) <=  ldzPane.getWidth() + startX + buffer) &&
            //      ((newXPosition.get() + startX + imgView.getImage().getWidth()+ buffer)<=  ldzPane.getWidth()))
                imgView.setTranslateX(newXPosition.get());

            //if(       (Math.abs((newYPosition.get() - ldzPane.getHeight())) <=  ldzPane.getHeight() + startY + buffer) &&
            //      ((newYPosition.get() + startY + imgView.getImage().getHeight()+ buffer)<=  ldzPane.getHeight()))
                imgView.setTranslateY(newYPosition.get());

            event.consume();
        }

    });

    imgView.setOnDragDone(new EventHandler<DragEvent>() {
        public void handle(DragEvent event) {

            LinkedList<RHSIconizedToken> iTokens = GameBoard.getInstance().getTokenBayItokens();
            if (event.getTransferMode() == TransferMode.MOVE) {
                RHSIconizedToken element = iTokens.remove(index);
                iTokens.add(index, new RHSIconizedToken(element.getImage(), new SourceToken("removed", "removed"), index));
                imgView.setVisible(false); 

                GameBoard theGameBoard = GameBoard.getInstance();
                GUI theGUI = GUI.getInstance();
                //was this the last one removed from the rhs?
                //if so we need to signal the CompileButton to be turned on!
                if(theGameBoard.isRHSempty())
                    theGUI.enableCompileButton();
                else
                    theGUI.disableCompileButton();
            }
            event.consume();
        }
    });

    imgView.setOnMouseEntered(new EventHandler <MouseEvent>() {
        public void handle(MouseEvent event) {
            imgView.setEffect(new Glow(0.5));
            event.consume();
        }
    });

    imgView.setOnMouseExited(new EventHandler <MouseEvent>() {
        public void handle(MouseEvent event) {
            imgView.setEffect(new Glow(0.0));
            imgView.setOpacity(1);
            event.consume();
        }
    });

    return imgView;
}

共有2个答案

洪伟彦
2023-03-14

我认为这将帮助你:

DraggablePanelsExample.java

我也在我的面板上使用了这个,它对ImageView很有吸引力。

编辑:
您正在合并此错误!不能将DragDetected与MouseDragged结合使用。如果开始在JavaFX中拖动,mouseevents将不再被触发<如果你想要一个拖板字符串,那么只需将字符串保存在类中。

ps:用鼠标替换DragDone

蔚和风
2023-03-14

Java 8计划提供更多对可视化拖放的支持。DragBoard的setDragView(Image,XOffset,YOffset)方法非常有效,可以在Java8beta中使用。

    imgView.setOnDragDetected(new EventHandler<MouseEvent>() {
        public void handle(MouseEvent event) {
            ClipboardContent content = new ClipboardContent();
            content.putString(RHSIconizedToken.this.tokenLookupInfo());
            Dragboard db = imgView.startDragAndDrop(TransferMode.ANY);
            db.setDragView(image, 7, 7); 
            db.setContent(content); 
            event.consume();
        }
    });
 类似资料:
  • 我已经编写了一个服务器-客户端(两个程序)结构,它工作正常。。。仅当使用TCP时。我的想法是使用TCP进行文本聊天传输(udp不可靠),但使用udp进行游戏数据包传输(是的,这是一种每秒30帧的动作游戏,所以我需要udp)。 但是,当我在客户端进程中与TCP建立连接时,我开始向服务器程序发送UDP数据包,并从服务器程序接收UDP数据包。客户端在单个线程中使用非阻塞套接字、UDP和TCP。这里没有多

  • 如何监控LMAX Disruptor?假设我有3个环缓冲区,并希望提供一个用户界面来提供环缓冲区的信息。

  • 我试图做的是防止用户在我的输入中输入空字符串。现在,用户只能输入数字。然而,没有什么能阻止他们将文本字段留空。我想限制他们在程序空白时按我的按钮启动程序。 现在,我的文本字段最初是空白的,按钮最初是灰色的。但当我输入一些东西时,按钮保持灰色。请记住,所有这些代码都在构造函数中。

  • 概述 无干扰模式将只在显示器中以全屏模式显示你的文件,可以在菜单栏中的View - 切换无干扰模式进入无干扰模式,快捷键也可以。 定制化 无干扰模式将使某些设置生效,默认设置(位于Packages/Default/Distraction Free.sublime-settings)是: { "line_numbers": false, "gutter": false, "draw_ce

  • 我已经在Codeigniter上编写了一个简单的身份验证过程,但存在一个问题。 由于某些原因,当用户浏览站点时,会话会被混淆,并模拟另一个随机用户。 我只是做: 我通过

  • 我需要从同一个套接字或者从$*IN中读取多个线程;然而,似乎有错误,因为每个都试图从相同的来源读取(我认为)。解决这个问题的最好方法是什么?谢谢!! 以下是错误: 谢谢!!