拖放过程中改变光标在JavaFX的ListView(Change cursor in JavaFx

2019-09-29 18:59发布

我有一个列表视图,我使人们有可能通过重新排列拖和下降的元素,它工作正常,但我想用我自己的自定义的替换两个默认的图标。 我曾尝试与这两个的ListCell本身或其父母即的setCursor(Cursor.HAND)的setCursor(新ImageCursor(图片)),但没有得到体现拖动过程中,只有后,这不是我想要的。 任何人都知道如何去吗?

EDIT1:这个问题有没有关系如何创建一个重新排序,能够列表视图。 它是关于如何将ListView项的拖放和下降过程中更改默认光标。 这不是重复
如何创建JavaFX中重排,能够TableView中 ,因为它也有拖欧米茄下降过程中非常相同的默认光标的图标。

EDIT2:影响Windows和Linux操作系统:ES根据我的调查结果,不支持Mac OS X.

截图拖N -降不准图标

截图拖N -降允许图标

package sample;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.*;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception{

        Pane pane = new Pane();
        ObservableList<String> items = FXCollections.observableArrayList("test1", "test2", "test3", "test4");
        ListView<String> lw = new ListView<>();
        lw.setCellFactory(param -> new MyListCell());
        lw.setItems(items);
        pane.getChildren().add(lw);
        stage.setTitle("RearrangeListView");
        stage.setScene(new Scene(pane, 300, 150));
        stage.show();
    }

    private class MyListCell extends ListCell<String> {

        public MyListCell() {

            setOnDragDetected(event -> {

                if (getItem() == null) {
                    return;
                }

                if (event.getButton() == MouseButton.PRIMARY) {
                    WritableImage image = snapshot(new SnapshotParameters(), null);
                    Dragboard dragboard = startDragAndDrop(TransferMode.MOVE);
                    ClipboardContent content = new ClipboardContent();
                    content.putString("abc");
                    dragboard.setDragView(image);
                    dragboard.setContent(content);
                    //setCursor(Cursor.HAND);
                    event.consume();
                }
            });

            setOnDragOver(event -> {
                if (event.getGestureSource() != this && event.getDragboard().hasString()) {
                    event.acceptTransferModes(TransferMode.MOVE);
                }
                event.consume();
            });

            setOnDragEntered(event -> {
                if (event.getGestureSource() != this && event.getDragboard().hasString()) {
                    setOpacity(0.3);
                }
            });

            setOnDragExited(event -> {
                if (event.getGestureSource() != this && event.getDragboard().hasString()) {
                    setOpacity(1);
                }
            });

            setOnDragDropped(event -> {
                if (getItem() == null) {
                    return;
                }

                Dragboard db = event.getDragboard();
                boolean success = false;

                if (db.hasString()) {

                    ObservableList<String> items = getListView().getItems();
                    String source = ((MyListCell) event.getGestureSource()).getItem();
                    String target = ((MyListCell) event.getGestureTarget()).getItem();

                    int sourceIdx = items.indexOf(source);
                    int targetIdx = items.indexOf(target);

                    //swap
                    items.set(sourceIdx, target);
                    items.set(targetIdx, source);

                    success = true;
                }

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

            setOnDragDone(DragEvent::consume);
        }

        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (empty || item == null) {
                setText(null);
            } else {
                setText(item);
            }
        }
    }

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

Answer 1:

OK,我想现在明白我的误解。 JavaFX的支持一个DragView和光标,并在同一时间显示他们。 所以我觉得你问的是如何展现要么只有DragView或两个DragView和自定义光标。

这样做的一种方法是修改的答案: 如何创建JavaFX中重排,能够TableView中 ,有以下变化:

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);

我测试了OS X程序和它的工作对我来说,你的里程可能会有所不同。 需要注意的是光标操作可以跨操作系统不同(例如,没有这个答案的变化,在OS X上,拖动时,我没有得到光标框,你看到在Windows上,我只是得到一个默认的箭头光标除了DragView图像)。

上述变化似乎只要你周围的物体在场景中拖动到工作。 如果拖动阶段外,然后将光标恢复到默认光标(我没有为一个固定的JavaFX的不允许光标的控制,一旦经过现场外)。



文章来源: Change cursor in JavaFx ListView during drag and drop