我想在拖放事件中设置自定义光标。我想将光标覆盖为例如经典的开手一号。
b.setOnDragDetected(e -> {
Dragboard db = b.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString("");
db.setContent(content);
b.setCursor(Cursor.CLOSED_HAND);
});
b.setOnDragOver(e -> {
if (e.getSource() != b)
e.acceptTransferModes(TransferMode.MOVE);
b.setCursor(Cursor.CLOSED_HAND);
});
不幸的是 DragEvent.acceptTransferModes() 将光标设置为移动/链接/复制之一并忽略了我的更改。有没有办法设置任何其他光标?
由于您没有发布 MVCE,我们只能猜测问题出在哪里,我写了一个简单的示例来显示所有类型的拖放事件。我猜你没有将 Cursor 重置为默认值?
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.ImageCursor;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MainApp extends Application {
@Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
pane.setMinSize(400, 400);
pane.setPadding(new Insets(10));
Button b = new Button("Drag Source (b)");
Button c = new Button("Drag Target (c)");
//here we load a custom image
Image img = new Image("http://2.bp.blogspot.com/-ipjep9g59YY/VbqLU1vD9qI/AAAAAAAAAOc/CjB4YvRYz_M/s1600/skype-drunk.jpg");
b.setOnDragOver(event->{
if (event.getGestureSource() != b && event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.MOVE);
System.out.println("DragOver (b)");
}
event.consume();
});
b.setOnDragDropped(e -> {
System.out.println("DragDropped (b)");
//added following line as cursor wasn´t reseted to default
b.setCursor(Cursor.DEFAULT);
e.setDropCompleted(true);
e.consume();
});
b.setOnDragExited(event->{
event.consume();
System.out.println("DragExited (b)");
});
b.setOnDragDetected(e-> {
Dragboard db = b.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString("Hey i´m b");
db.setContent(content);
//b.setCursor(Cursor.OPEN_HAND);
b.setCursor(new ImageCursor(img));
e.consume();
});
b.setOnDragDone(event->{
/* the drag and drop gesture ended */
/* if the data was successfully moved, do something and reset Cursor */
if (event.getTransferMode() == TransferMode.MOVE) {
//b.setCursor(Cursor.DEFAULT);
}
b.setCursor(Cursor.DEFAULT);
event.consume();
});
c.setOnDragOver(event->{
if (event.getGestureSource() != c && event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.MOVE);
System.out.println("DragOver (c)");
}
event.consume();
});
c.setOnDragDropped(e -> {
System.out.println("DragDropped (c)");
e.setDropCompleted(true);
e.consume();
});
c.setOnDragExited(event->{
event.consume();
System.out.println("DragExited (c)");
});
c.setOnDragDetected(e-> {
Dragboard db = c.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString("Hey i´m c");
db.setContent(content);
c.setCursor(Cursor.OPEN_HAND);
e.consume();
});
c.setOnDragDone(event->{
/* the drag and drop gesture ended */
/* if the data was successfully moved, do something and reset Cursor */
if (event.getTransferMode() == TransferMode.MOVE) {
c.setCursor(Cursor.DEFAULT);
}
event.consume();
});
VBox box = new VBox(b,c);
box.setSpacing(20);
BorderPane root = new BorderPane(pane, box, null, null, null);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我想你可以尝试根本不使用 DragBoard,只是将拖动的项目保存在局部变量中,然后从那里接收它,在我看来,只是不要将 dragBoard.startDragAndDrop() 函数与该 TransferMode 一起使用。相反,只需编写该功能,这就是我如何防止 Java DragBoard 设置那个丑陋的系统光标!我知道如果您将数据(字符串、Html、文件)从操作系统中拖出,它将使用更好的操作系统拖动光标标签和一些系统文本,如“复制文件”或“链接”,但如果您只需要拖动一些内部Java 对象不需要使用那个 DragBoard,它无论如何都会显示这些丑陋的空光标标签。但是您仍然可以使用这些 setOnMouseDragged() 方法。