【发布时间】:2021-05-24 12:53:20
【问题描述】:
我遇到了下一个问题.. 我在我的应用程序中添加了一个简单的 drag-n-drop 功能,以将卡片从左右 ListView 移动到中心表。该表只是一个GridView。网格子元素完美接收到任何拖动事件,没关系。
但是.. 如果我调整应用程序窗口的大小,我无法将卡片拖动到 GridView 的右侧和底部。可能这个 GridView 只是调整大小,但 JavaFX 拖动提供程序只是使用旧边界?我如何修复它并向拖动提供者“说”新的 GridView 尺寸?
工作环境:
- Oracle JDK 11.0.9
- 自定义 JavaFX 11.0.2 运行时映像
- Linux(内核 5.10.11,内部版本 170)
- GTK 2(使用
-Djdk.gtk.version=2为 JFX 应用程序指定)
DragAndDropProvider.java(主 DnD 类):
public class DragAndDropProvider {
public static final DataFormat SUBJECT_DATA_FORMAT = new DataFormat(SubjectCard.class.getName());
public static final DataFormat TEACHER_DATA_FORMAT = new DataFormat(TeacherCard.class.getName());
public static <T extends DatabaseCellDto<CARD>, CARD> void allowDragSourceFeature(ListView<T> listView) {
listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
listView.setOnDragDetected(event -> dragDetected(event, listView));
listView.setOnDragDone(event -> dragDone(event, listView));
}
public static void allowDragTargetFeature(LessonDto lesson) {
lesson.setOnDragOver(DragAndDropProvider::dragOver);
}
private static <T extends DatabaseCellDto<CARD>, CARD> void dragDetected(MouseEvent event, ListView<T> listView) {
// make sure at list item is selected
T selectedItem = listView.getSelectionModel().getSelectedItem();
if(selectedItem == null) {
event.consume();
return;
}
// determining the date format
DataFormat dataFormat;
CARD card = selectedItem.getCard();
if(card instanceof SubjectCard)
dataFormat = SUBJECT_DATA_FORMAT;
else if(card instanceof TeacherCard)
dataFormat = TEACHER_DATA_FORMAT;
else
throw new RuntimeException("Unsupported transfer object type: " + card.getClass().getSimpleName());
// initiate a drag-and-drop gesture
Dragboard dragboard = listView.startDragAndDrop(TransferMode.ANY);
// put the selected item to the dragboard
ClipboardContent content = new ClipboardContent();
content.put(dataFormat, selectedItem.getCard());
dragboard.setContent(content);
event.consume();
}
private static void dragOver(DragEvent event) {
// if drag board has an ITEM_LIST and it is not being dragged
// over itself, we accept the MOVE transfer mode
Dragboard dragboard = event.getDragboard();
if(dragboard.hasContent(SUBJECT_DATA_FORMAT) || dragboard.hasContent(TEACHER_DATA_FORMAT))
event.acceptTransferModes(TransferMode.ANY);
event.consume();
}
private static void dragDropped(DragEvent event, LessonDto target) {
// transfer the data to the target
Dragboard dragboard = event.getDragboard();
boolean dragCompleted = false;
if(dragboard.hasContent(SUBJECT_DATA_FORMAT)) {
SubjectCard content = (SubjectCard) dragboard.getContent(SUBJECT_DATA_FORMAT);
target.updateSubject(content);
dragCompleted = true;
} else if(dragboard.hasContent(TEACHER_DATA_FORMAT)) {
TeacherCard content = (TeacherCard) dragboard.getContent(TEACHER_DATA_FORMAT);
target.updateTeacher(content);
dragCompleted = true;
}
event.setDropCompleted(dragCompleted);
event.consume();
}
}
【问题讨论】:
-
minimal reproducible example 请..用英文,请:)