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

受窗口大小调整影响的JavaFX拖动事件

陈斌
2023-03-14

我一直在尝试在JavaFX中实现节点拖动,我遇到了一个似乎应该相对容易解决的问题。我猜这与调整窗口大小后JavaFX场景图如何更新(或不更新)有关。

无论如何,问题如下:

应用程序在一个小窗口中启动,其中有一个节点可以在窗口中单击和拖动。这在两种情况下都可以正常工作:

  1. 在调整大小之前,单击并在窗口中拖动节点。
  2. 调整大小后,单击节点并在窗口中拖动。

但在第三种情况下失败:

拖动事件似乎无法识别窗口边界中的更改。换句话说,如果单击并拖动节点,则放大窗口。随后的单击和拖动尝试将限于窗口的原始边界。

无论如何,下面是我为演示这个问题而编写的JavaFX应用程序示例。它复制了我上面描述的三个测试用例。

谢谢。

import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.application.Application;
import javafx.event.EventHandler;

public class Main extends Application {

private AnchorPane node_root;
private BorderPane mRoot;

@Override
public void start(Stage primaryStage) {

    try {
        node_root = new AnchorPane();
        mRoot = new BorderPane();
        Scene scene = new Scene(mRoot,400,400);

        primaryStage.setScene(scene);
        primaryStage.show();

    } catch(Exception e) {
        e.printStackTrace();
    }

    addFileSystemNode ();

    mRoot.setOnDragDone (new EventHandler <DragEvent>() {

        @Override
        public void handle(DragEvent event) {
System.out.println ("Drag done");
            event.consume();
        }
    });     
}

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

public final void addFileSystemNode () {

    Label node_title = new Label();
    node_title.setText("drag me!");

    node_root.getChildren().add (node_title);
    mRoot.getChildren().add (node_root);

    buildNodeDragHandlers();        

    node_root.setLayoutX(100.0);
    node_root.setLayoutY(100.0);
}

public void relocateToPoint (Point2D p) {
    Point2D p2 = mRoot.sceneToLocal(p);

    node_root.relocate (
            (int) (p2.getX()),
            (int) (p2.getY())
        );
}

public void buildNodeDragHandlers() {

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

        //dragover to handle node dragging in the right pane view
        @Override
        public void handle(DragEvent event) {   

            System.out.println("parent node drag over" + " "  + ((Pane) event.getSource()).getId());

            event.acceptTransferModes(TransferMode.ANY);
            relocateToPoint(new Point2D( event.getSceneX(), event.getSceneY()));
            event.consume();
        }
    });

    mRoot.setOnDragDropped(new EventHandler <DragEvent> () {

        @Override
        public void handle(DragEvent event) {

            System.out.println("node drag dropped");                

            event.setDropCompleted(true);
            event.consume();
        }
    });     

    //drag detection for node dragging
    node_root.setOnDragDetected( new EventHandler <MouseEvent> () {

        @Override
        public void handle(MouseEvent event) {

            System.out.println("Drag detected");                

            //begin drag ops
            relocateToPoint(new Point2D(event.getSceneX(), event.getSceneY()));

            ClipboardContent content = new ClipboardContent();
            content.putString("node_drag");

            node_root.startDragAndDrop (TransferMode.ANY).setContent(content);                

            event.consume();                    
        }

    });     
}   
}

共有2个答案

暴招
2023-03-14

这个错误是Linux平台特有的。我测试了我的代码,你的和在视窗7上一切正常,但是Linux出现了错误。(我还没有在MacOS上测试过)。

我使用: OpenJdk 11.0.2

JDK问题跟踪器中的问题:

https://bugs.openjdk.java.net/browse/JDK-8088458

还有一个与拖放和GTK3相关的错误:

https://bugs.openjdk.java.net/browse/JDK-8214083

龚鸿羽
2023-03-14

这似乎是JavaFX中的一个真正的bug。提交了一份bug报告。目前计划在JDK 9中进行修复

https://javafx-jira.kenai.com/browse/RT-39892

 类似资料:
  • 我正在尝试构建一个包含6个窗格(作为父级添加到GridPane布局中)的简单Java项目。我必须在开始时设置窗口大小,并通过参考根布局的宽度和高度,设法将它们均匀地拆分。 但我想要他们调整大小,因为我改变了窗口的大小(使用鼠标,现在他们得到固定的大小)。 下面是我的代码:

  • 问题内容: 我正在使用Java编写一个简单的绘画程序,并且每当调整JFrame组件的大小时,我都希望调用某种方法。但是我找不到像windowResizedListener之类的任何方法或诸如windowResizedEvent之类的事件。我能做什么?! 问题答案: 实现一个具有:

  • 问题内容: 如何挂接到浏览器窗口调整大小事件? 有一种jQuery侦听调整大小事件的方法,但我不希望仅出于这一要求就将其引入我的项目中。 问题答案: jQuery只是包装了标准的DOM事件,例如。 jQuery 可以 做一些工作来确保在所有浏览器中一致地触发resize事件,但是我不确定任何浏览器是否有所不同,但是我建议您在Firefox,Safari和IE中进行测试。

  • 我的场景中有一个对象。我希望能够调整窗口的大小,并与它一起调整窗格的大小。我还想在窗格旁边放置一个。 到目前为止,我已经成功地生成了一个完全可调整大小的或一个,其中包含和对象,但当我调整窗口大小时,窗格不会随之调整大小。 以下是带有锚烷的FXML: 只有的版本基本上就是版本中使用的代码,但具有和属性。 如何制作一个场景,使其具有可调整大小的和?

  • 问题内容: 我想基于窗口重新调整大小事件(在加载和动态运行)执行一些任务。 目前,我的DOM如下: 该事件正确触发 如何从此事件对象中检索宽度和高度? 谢谢。 问题答案:

  • 窗口大小,我们可以非常方便的使用width、height调整,但是如何知道 width和height是一个问题? 在 Window 操作系统中,假如我们想要缩放,我们通常会把鼠标移动到窗口的右边栏,和底部边栏,以及右下边栏。 而且在不同的边栏,鼠标呈现的样式也是不一样的。当我们在右边栏的时候我们可以通过cursor: e-resize;模拟鼠标样式。 在底部边栏我们可以通过cursor: s-re