我正在使用拖放功能创建一个javafx应用程序。我需要能够从一个窗格拖动并放到下一个窗格。删除后,所有丢弃的节点都需要可访问。拖放工作顺利进行。但是,我遇到的问题是,丢弃后并非所有节点都可访问。我会拖动一个节点并单击它,有时它会响应,但有时当我点击它时,随机节点将不再展示功能。关于哪些节点停止工作以及哪些节点始终有效,没有明显的模式(我可以看到)。如果有人知道为什么这可能是一个问题或如何解决它,将不胜感激。几年前我到处寻找并发现只有一个类似的问题,但是他们的解决方案页面已被删除。
我将简要介绍如何设置代码结构。 我拖动的节点扩展了StackPane,我将这些节点从VBox中的ImageView拖到中心窗格上。但是,这两个都是扩展BorderPane的Main布局的子代,我称之为MainEntrance。 在我的节点类中,我有onMousePressed和onMouseDragged特性以及onContextMenuRequested特性。在MainEntrance的类中,我还有拖动功能,可以处理对象首次从另一个子VBox拖到子窗格上时。
以下是相关的课程/方法:
VBox类:(从中拖出节点)
ImageView iV= new ImageView(image);
iV.setId("image");
iV.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
dragAndDrop(iV, iV.getId(), event);
}
});
我拖了三个ImageViews,这些ImageViews是VBox的孩子。
MainEntrance: 在这个类中,我有一个方法可以将我的拖动事件注册到我的窗格中: PView是我的Pane的类扩展
public void registerOnDragDropped(PView pView){
pView.setOnDragOver(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
event.acceptTransferModes(TransferMode.ANY);
System.out.println("drag over registered");
}
});
pView.setOnDragDropped(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
final String id = db.getString();
double mousePosY = event.getY();
double mousePosX = event.getX();
deviceCounter += 1;
pView.createBoardView(id, deviceCounter, mousePosX, mousePosY);
event.setDropCompleted(true);
}
});
pView.setOnDragExited(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
event.acceptTransferModes(TransferMode.ANY);
//computerView.setEffect(null);
event.consume();
}
});
}
注意:此方法位于我的MainEntrance类(BorderPane)中。在这个类中,我初始化MainEntrance的所有其他子节点。
节点:(可拖动节点扩展StackPane) 我的节点处理程序位于我调用makeDraggable()
的方法中public void makeDraggable(Node node) {
this.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
node.getScene().setCursor(Cursor.MOVE);
System.out.println("makeDraggable mouse pressed");
}
});
node.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
node.getScene().setCursor(Cursor.DEFAULT);
}
});
node.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
node.setTranslateX(node.getTranslateX() + event.getX() - 35);
node.setTranslateY(node.getTranslateY() + event.getY() - 35);
event.consume();
node.toFront();
}
});
}
如果需要任何其他信息,请告诉我。提前谢谢!
答案 0 :(得分:0)
我已经找到了解决这个问题的方法。
问题在于我放置在节点上的附件的呈现顺序。因此,当我将节点拖到屏幕上时,我有另一个节点(放置在窗格上的一条线)将屏幕中心绑定到节点。我最初并不认为这是问题,所以我甚至没有包含那个类或片段。然而,在玩完它后,我意识到这确实是问题所在。我必须将该行添加到渲染顺序的顶部。无论您使用何种方法创建新节点,都可以通过以下方式完成此操作:
Pane line = new Pane();
//add whatever code binds your line to desired places
getChildren.add(0, line);
//add the other node as child