如何找到位于javafx中放置位置的ListCell

时间:2017-04-19 20:19:38

标签: javafx javafx-8

我有一个ListView,它是一个拖拉目标。处理OnDragDropped事件时,我想找到位于鼠标位置的列表单元格。此外,我想在鼠标悬停在它们上方时突出显示项目,即使在拖放操作期间也是如此。如何在JavaFx中实现这一目标。

1 个答案:

答案 0 :(得分:0)

使用列表视图上的单元工厂来定义自定义单元格:这样,您可以使用单个单元格而不是列表视图注册拖动处理程序。然后拖动处理程序很容易知道哪些单元格已经触发了事件。

这是一个SSCCE:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class ListViewWithDragAndDrop extends Application {

    @Override
    public void start(Stage primaryStage) {
        ListView<String> listView = new ListView<>();
        listView.getItems().addAll("One", "Two", "Three", "Four");

        listView.setCellFactory(lv -> {
            ListCell<String> cell = new ListCell<String>() {
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty) ;
                    setText(item);
                }
            };
            cell.setOnDragOver(e -> {
                Dragboard db = e.getDragboard();
                if (db.hasString()) {
                    e.acceptTransferModes(TransferMode.COPY);
                }
            });
            cell.setOnDragDropped(e -> {
                Dragboard db = e.getDragboard();
                if (db.hasString()) {
                    String data = db.getString();
                    if (cell.isEmpty()) {
                        System.out.println("Drop on empty cell: append data");
                        listView.getItems().add(data);
                    } else {
                        System.out.println("Drop on "+cell.getItem()+": replace data");
                        int index = cell.getIndex();
                        listView.getItems().set(index, data);
                    }
                    e.setDropCompleted(true);
                }
            });

            // highlight cells when drag target. In real life, use an external CSS file
            // and CSS pseudoclasses....
            cell.setOnDragEntered(e -> cell.setStyle("-fx-background-color: gold;"));
            cell.setOnDragExited(e -> cell.setStyle(""));
            return cell ;
        });

        TextField textField = new TextField();
        textField.setPromptText("Type text and drag to list view");
        textField.setOnDragDetected(e -> {
            Dragboard db = textField.startDragAndDrop(TransferMode.COPY);
            String data = textField.getText();
            Text text = new Text(data);
            db.setDragView(text.snapshot(null, null));
            ClipboardContent cc = new ClipboardContent();
            cc.putString(data);
            db.setContent(cc);
        });

        BorderPane root = new BorderPane(listView, textField, null, null, null);
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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