File javafx-8:onDropOver从不为外部文件调用

File javafx-8:onDropOver从不为外部文件调用,file,drag-and-drop,javafx-8,fxml,File,Drag And Drop,Javafx 8,Fxml,我正在做我的第一个JavaFX项目 (我以前做过一些Swing,通常是C#前端和Java后端。) 设置: 该应用程序包含一个TableView,其中显示UploadFile的行,这是一个围绕java.io.File的自定义包装器,用于显示其他属性。这些文件最终将被上传到服务器 现在,我想添加一个选项,从操作系统资源管理器中拖动文件,如果文件具有正确的属性,则将其放到要添加的表中。 我还希望允许将文件从表中拖到垃圾区或表外,这将从表中删除文件 问题: 当我从表中拖动文件时,会调用handleDra

我正在做我的第一个JavaFX项目

(我以前做过一些Swing,通常是C#前端和Java后端。)

设置:

该应用程序包含一个TableView,其中显示UploadFile的行,这是一个围绕java.io.File的自定义包装器,用于显示其他属性。这些文件最终将被上传到服务器

现在,我想添加一个选项,从操作系统资源管理器中拖动文件,如果文件具有正确的属性,则将其放到要添加的表中。 我还希望允许将文件从表中拖到垃圾区或表外,这将从表中删除文件

问题:

当我从表中拖动文件时,会调用
handleDragDetected(MouseEvent e)

但是,如果我将文件从资源管理器拖到表中,则不会调用任何事件处理程序。(我在Windows10Pro上试过)

问题:

我是否需要以某种方式打开它,或者我在这里遗漏了什么

代码:

一些FXML:

<VBox fx:id="root" xmlns="http://javafx.com/javafx/8.0.40"
    xmlns:fx="http://javafx.com/fxml/1" 
    fx:controller="com.company.project.gui.controllers.FormController">
  <children>
    ..
    <TableView id="tbl-files" editable="true" 
        onDragDetected="#handleDragDetected" onDragOver="#handleDragOver"
        onDragEntered="#handleDragEntered" onDragExited="#handleDragExited"
        onDragDropped="#handleDragDropped" onDragDone="#handleDragDone">
      <columns> .. </columns>
    </TableView>
    ..
  </children>
</VBox> 
编辑1:

我还为
onMouseDrag..
事件添加了处理程序,并尝试在代码中而不是在FXML中添加它们。结果仍然是一样的。我想我现在的重点是把文件从表中拖出来,因为这似乎是可行的

编辑2:

我终于有时间对这件事做进一步的调查了

我实际上复制了一个完整的最小示例(见下文),得到了相同的结果。没有一个我甚至试图把听众放在现场本身,但这也不起作用。当我将一个文件拖到应用程序窗口中时,光标会改变以指示这是不允许的,而不会调用任何侦听器。(我的理解是在拒绝拖动之前应该调用onDragOver,因为这是应用程序决定在何种条件下接受拖动内容的地方。)

我还从命令行运行该程序,将JDK更新为8u66(32位和64位),然后重试。我不知道为什么它不起作用

package dragAndDropTest;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class DragAndDropTest extends Application {

  @Override
  public void start(Stage primaryStage) {
      Label label = new Label("Drag a file to me.");
      Label dropped = new Label("");
      VBox dragTarget = new VBox();
      dragTarget.getChildren().addAll(label,dropped);
      dragTarget.setOnDragOver(new EventHandler<DragEvent>() {

          @Override
          public void handle(DragEvent event) {
            System.out.println("DragOver: " + event.toString());
              if (event.getGestureSource() != dragTarget
                      && event.getDragboard().hasString()) {
                  /* allow for both copying and moving, whatever user chooses */
                  event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
              }
              event.consume();
          }
      });

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

          @Override
          public void handle(DragEvent event) {
            System.out.println("DragDropped: " + event.toString());
              Dragboard db = event.getDragboard();
              boolean success = false;
              if (db.hasString()) {
                  dropped.setText(db.getString());
                  success = true;
              }
              /* let the source know whether the string was successfully 
               * transferred and used */
              event.setDropCompleted(success);

              event.consume();
          }
      });


      StackPane root = new StackPane();
      root.getChildren().add(dragTarget);

      Scene scene = new Scene(root, 500, 250);

      primaryStage.setTitle("Drag Test");
      primaryStage.setScene(scene);
      primaryStage.show();
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
      launch(args);
  }

}
封装测试;
导入javafx.application.application;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.input.DragEvent;
导入javafx.scene.input.Dragboard;
导入javafx.scene.input.TransferMode;
导入javafx.scene.layout.StackPane;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类DragAndDropTest扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
Label Label=新标签(“将文件拖到我身边”);
标签已删除=新标签(“”);
VBox dragTarget=新的VBox();
dragTarget.getChildren().addAll(标签,已删除);
dragTarget.setOnDragOver(新的EventHandler(){
@凌驾
公共无效句柄(DrageEvent事件){
System.out.println(“DragOver:+event.toString());
如果(event.getGestureSource()!=dragTarget
&&event.getDragboard().haString()){
/*允许复制和移动,无论用户选择什么*/
事件.acceptTransferModes(TransferMode.COPY\u或\u MOVE);
}
event.consume();
}
});
setOnDragDropped(新的EventHandler(){
@凌驾
公共无效句柄(DrageEvent事件){
System.out.println(“dragdroped:+event.toString());
Dragboard db=event.getDragboard();
布尔成功=假;
if(db.hastring()){
drop.setText(db.getString());
成功=真实;
}
/*让源知道字符串是否已成功删除
*转让和使用*/
事件。setDropCompleted(成功);
event.consume();
}
});
StackPane root=新的StackPane();
root.getChildren().add(dragTarget);
场景=新场景(根,500250);
primaryStage.setTitle(“阻力测试”);
初级阶段。场景(场景);
primaryStage.show();
}
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
发射(args);
}
}

您的代码应该按原样工作。你能创建一个完整的示例并将其包含在你的问题中吗?很抱歉,我一直在忙其他事情,现在按照你的要求添加了一个完整的示例,但它对我不起作用。你知道这一点吗?我可能有一个解决方案,因为其他东西更重要,我已经有一段时间没有看它了——因为我记得它突然在一个较新的JDK版本中工作,所以在那个特定的JAVA版本中似乎是一个bug(不记得是哪个版本)-一定要把你的信寄出去answer@LorenShqipognja您的解决方案是什么?您的代码应该按原样工作。你能创建一个完整的示例并将其包含在你的问题中吗?很抱歉,我一直在忙其他事情,现在按照你的要求添加了一个完整的示例,但它对我不起作用。你知道这一点吗?我可能有一个解决方案,我已经有一段时间没有看它了,因为其他东西更重要——因为我记得它突然在一个较新的JDK版本中工作,所以在那个特定的JAVA版本中似乎是一个bug(不记得是哪个版本)——无论如何,请发布您的帖子answer@LorenShqipognja你的解决方案是什么?
package dragAndDropTest;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class DragAndDropTest extends Application {

  @Override
  public void start(Stage primaryStage) {
      Label label = new Label("Drag a file to me.");
      Label dropped = new Label("");
      VBox dragTarget = new VBox();
      dragTarget.getChildren().addAll(label,dropped);
      dragTarget.setOnDragOver(new EventHandler<DragEvent>() {

          @Override
          public void handle(DragEvent event) {
            System.out.println("DragOver: " + event.toString());
              if (event.getGestureSource() != dragTarget
                      && event.getDragboard().hasString()) {
                  /* allow for both copying and moving, whatever user chooses */
                  event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
              }
              event.consume();
          }
      });

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

          @Override
          public void handle(DragEvent event) {
            System.out.println("DragDropped: " + event.toString());
              Dragboard db = event.getDragboard();
              boolean success = false;
              if (db.hasString()) {
                  dropped.setText(db.getString());
                  success = true;
              }
              /* let the source know whether the string was successfully 
               * transferred and used */
              event.setDropCompleted(success);

              event.consume();
          }
      });


      StackPane root = new StackPane();
      root.getChildren().add(dragTarget);

      Scene scene = new Scene(root, 500, 250);

      primaryStage.setTitle("Drag Test");
      primaryStage.setScene(scene);
      primaryStage.show();
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
      launch(args);
  }

}