在拖放过程中更改JavaFXListView中的光标

在拖放过程中更改JavaFXListView中的光标,listview,javafx,drag-and-drop,icons,Listview,Javafx,Drag And Drop,Icons,我有一个listview,在那里我可以通过拖放重新排列元素,它工作得很好,但是我想用我自己的自定义图标替换两个默认图标。我在ListCell本身或它的父对象上都尝试过使用例如setCursor(Cursor.HAND)setCursor(new-ImageCursor(image)),但是在拖动过程中没有任何反射,只是在拖动之后,这不是我想要的。有人知道怎么做吗 Edit1:这个问题与如何创建可重新排序的列表视图无关。它是关于如何在拖放listview项期间更改默认光标。它不是的副本,因为在拖放

我有一个listview,在那里我可以通过拖放重新排列元素,它工作得很好,但是我想用我自己的自定义图标替换两个默认图标。我在ListCell本身或它的父对象上都尝试过使用例如setCursor(Cursor.HAND)setCursor(new-ImageCursor(image)),但是在拖动过程中没有任何反射,只是在拖动之后,这不是我想要的。有人知道怎么做吗

Edit1:这个问题与如何创建可重新排序的列表视图无关。它是关于如何在拖放listview项期间更改默认光标。它不是
的副本,因为在拖放过程中,它也具有非常相同的默认光标图标

Edit2:影响Windows和Linux操作系统:根据我的发现,不是Mac OS X

包装样品;
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.scene;
导入javafx.scene.Snapshot参数;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.image.WritableImage;
导入javafx.scene.input.*;
导入javafx.scene.layout.Pane;
导入javafx.stage.stage;
公共类主扩展应用程序{
@凌驾
public void start(Stage)引发异常{
窗格=新窗格();
ObservableList items=FXCollections.observableArrayList(“test1”、“test2”、“test3”、“test4”);
ListView lw=新建ListView();
setCellFactory(参数->新建MyListCell());
lw.设置项目(项目);
pane.getChildren().add(lw);
stage.setTitle(“列表视图”);
舞台场景(新场景(窗格,300150));
stage.show();
}
私有类MyListCell扩展了ListCell{
公共MyListCell(){
检测到SetOnDrag(事件->{
如果(getItem()==null){
返回;
}
if(event.getButton()==MouseButton.PRIMARY){
WritableImage=快照(新快照参数(),null);
Dragboard Dragboard=startDragAndDrop(传输模式.移动);
ClipboardContent=新的ClipboardContent();
content.putString(“abc”);
dragboard.setDragView(图像);
拖板。设置内容(内容);
//setCursor(Cursor.HAND);
event.consume();
}
});
setOnDragOver(事件->{
if(event.getGestureSource()!=this&&event.getDragboard().haString()){
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
});
setOnDragEntered(事件->{
if(event.getGestureSource()!=this&&event.getDragboard().haString()){
不透明度(0.3);
}
});
setOnDragExited(事件->{
if(event.getGestureSource()!=this&&event.getDragboard().haString()){
毛不透明度(1);
}
});
SetOnDragDrop(事件->{
如果(getItem()==null){
返回;
}
Dragboard db=event.getDragboard();
布尔成功=假;
if(db.hastring()){
ObservableList items=getListView().getItems();
字符串源=((MyListCell)event.getGestureSource()).getItem();
字符串目标=((MyListCell)event.getGestureTarget()).getItem();
int sourceIdx=items.indexOf(source);
int targetIdx=items.indexOf(目标);
//交换
items.set(sourceIdx,target);
items.set(targetIdx,source);
成功=真实;
}
事件。setDropCompleted(成功);
event.consume();
});
setOnDragDone(DragEvent::consume);
}
@凌驾
受保护的void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
if(空| |项==null){
setText(空);
}否则{
setText(项目);
}
}
}
公共静态void main(字符串[]args){
发射(args);
}
}

好的,我想我现在明白我的误解了。JavaFX支持DragView和光标,并同时显示它们。因此,我认为您要问的是如何仅显示DragView或同时显示DragView和自定义光标

一种方法是通过以下更改将答案修改为::

private ImageCursor dragCursor;
. . .
// inside start()
dragCursor = new ImageCursor(
    new Image(
        "https://cdn2.iconfinder.com/data/icons/web/512/Cursor-512.png", 
        32, 32, true, true
    )
);
// at the end of setOnDragDetected()
getScene().setCursor(dragCursor);
// change setOnDragDone() to:
setOnDragDone(event -> {
    event.consume();
    getScene().setCursor(Cursor.DEFAULT);
});
如果不需要光标而不是自定义图像光标,则可以调用:

getScene().setCursor(Cursor.NONE);
我在OSX上测试了这个程序,它在那里对我有效,你的里程数可能会有所不同。请注意,光标处理在不同的操作系统中可能有所不同(例如,如果没有此答案中的更改,在OS X上,当拖动时,我不会得到您在Windows上看到的带有框的光标,除了DragView图像之外,我只会得到默认的箭头光标)


只要在场景中围绕对象拖动,上面的更改似乎就起作用。如果将光标拖到舞台外,光标将恢复为默认光标(我没有解决方法,因为JavaFX不允许在光标经过场景外时控制光标)。

好的,我想现在理解我的误解了。JavaFX支持DragView和光标,并同时显示它们。因此,我认为您要问的是如何仅显示DragView或同时显示DragView和自定义光标

一种方法是使用
getScene().setCursor(Cursor.NONE);