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

时间:2015-01-26 12:33:04

标签: javafx drag-and-drop javafx-2 java-8

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

无论如何,问题如下:

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

  1. 在调整大小之前,单击并拖动窗口中的节点。
  2. 在调整大小后,单击并在窗口中拖动节点。
  3. 但是第三次​​失败了:

    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 个答案:

答案 0 :(得分:0)

看来这是JavaFX中的一个真正的错误。提交了一份错误报告。目前计划在JDK 9中修复

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

答案 1 :(得分:0)

此错误特定于Linux平台。 我测试了我的代码,在Windows 7上您的和一切都还好,但是在Linux上出现了错误。 (我尚未在MacO上对其进行测试。)

我使用过:OpenJdk 11.0.2

JDK问题跟踪器中的问题:

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

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

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