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