我想在JavaFX中使用拖放功能,并且可以在视觉上看到被拖动的项目。我已经实现了我认为可行的解决方案,但API似乎存在问题。
根据API,startDragAndDrop(TransferMode ...)必须在setOnDragDetected内初始化。这是我使用Dragboard存储我希望转移到另一个节点的内容的地方。
编辑:这似乎与TrasferMode有关。如果我使用TransferMode.NONE没有问题,但使用COPY,ANY,LINK总会导致此问题。
但是调用dragBoard.setContent(一些剪贴板内容)只允许使用鼠标进行非常小的移动增量(任何方向最多4个像素!)。删除这行代码后,我可以拖动项目并将其拖动到任何地方,但当然,我无法存储剪贴板内容。
我看到的问题是在setOnDragDetected之前调用setOnMouseDragged(..)!在setOnDragDetected之前运行setOnMouseDragged为什么没有多大意义...
我的代码中有什么明显的东西可能导致问题吗?我只是希望能够在拖动时看到imgView移动,并且能够像往常一样使用剪贴板内容将其放在目标上。
编辑2:更新了以下代码,以反映仅使用拖动事件,而不是使用拖动和鼠标事件。使用两者引起的问题。仍然存在的问题是我无法删除目标,因为使用setOnDragOver会使拖动的节点始终位于光标下方。
protected ImageView initImageView(Image img){
final Pane ldzPane = GameBoard.getInstance().getLDZpane();
final ObjectProperty<Point2D> dragAnchor = new SimpleObjectProperty<>();
final ImageView imgView = new ImageView(img);
final DoubleProperty initX = new SimpleDoubleProperty();
final DoubleProperty initY = new SimpleDoubleProperty();
final DoubleProperty dragX = new SimpleDoubleProperty();
final DoubleProperty dragY = new SimpleDoubleProperty();
final DoubleProperty newXPosition = new SimpleDoubleProperty();
final DoubleProperty newYPosition = new SimpleDoubleProperty();
final int buffer = 3;
imgView.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
initX.set(imgView.getTranslateX());
initY.set(imgView.getTranslateY());
dragAnchor.set(new Point2D(event.getSceneX(), event.getSceneY()));
ClipboardContent content = new ClipboardContent();
content.putString(RHSIconizedToken.this.tokenLookupInfo());
Dragboard db = imgView.startDragAndDrop(TransferMode.ANY);
db.setContent(content);
event.consume();
}
});
imgView.setOnDragOver(new EventHandler<DragEvent>(){
@Override
public void handle(DragEvent event) {
imgView.toFront();
dragX.set(event.getSceneX() - dragAnchor.get().getX());
dragY.set(event.getSceneY() - dragAnchor.get().getY());
imgView.setOpacity(0.5);
newXPosition.set(initX.get() + dragX.get());
newYPosition.set(initY.get() + dragY.get());
//if( (Math.abs((newXPosition.get() - ldzPane.getWidth())) <= ldzPane.getWidth() + startX + buffer) &&
// ((newXPosition.get() + startX + imgView.getImage().getWidth()+ buffer)<= ldzPane.getWidth()))
imgView.setTranslateX(newXPosition.get());
//if( (Math.abs((newYPosition.get() - ldzPane.getHeight())) <= ldzPane.getHeight() + startY + buffer) &&
// ((newYPosition.get() + startY + imgView.getImage().getHeight()+ buffer)<= ldzPane.getHeight()))
imgView.setTranslateY(newYPosition.get());
event.consume();
}
});
imgView.setOnDragDone(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
LinkedList<RHSIconizedToken> iTokens = GameBoard.getInstance().getTokenBayItokens();
if (event.getTransferMode() == TransferMode.MOVE) {
RHSIconizedToken element = iTokens.remove(index);
iTokens.add(index, new RHSIconizedToken(element.getImage(), new SourceToken("removed", "removed"), index));
imgView.setVisible(false);
GameBoard theGameBoard = GameBoard.getInstance();
GUI theGUI = GUI.getInstance();
//was this the last one removed from the rhs?
//if so we need to signal the CompileButton to be turned on!
if(theGameBoard.isRHSempty())
theGUI.enableCompileButton();
else
theGUI.disableCompileButton();
}
event.consume();
}
});
imgView.setOnMouseEntered(new EventHandler <MouseEvent>() {
public void handle(MouseEvent event) {
imgView.setEffect(new Glow(0.5));
event.consume();
}
});
imgView.setOnMouseExited(new EventHandler <MouseEvent>() {
public void handle(MouseEvent event) {
imgView.setEffect(new Glow(0.0));
imgView.setOpacity(1);
event.consume();
}
});
return imgView;
}
答案 0 :(得分:3)
Java 8计划附带更多视觉拖放支持。 DragBoard的setDragView(Image,XOffset,YOffset)方法效果很好,可以在Java 8 beta中使用。
imgView.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
ClipboardContent content = new ClipboardContent();
content.putString(RHSIconizedToken.this.tokenLookupInfo());
Dragboard db = imgView.startDragAndDrop(TransferMode.ANY);
db.setDragView(image, 7, 7);
db.setContent(content);
event.consume();
}
});
答案 1 :(得分:2)
我认为这会对你有所帮助:
我也将它用于我的面板,它适用于ImageView,就像魅力一样。
修改强>
你结合这个假!您无法将DragDetected与MouseDragged结合使用。
如果你开始在JavaFX中拖动,那么mouseevents就不会再被触发了。
如果你想要一个Drag-Board-String,那么只需在你的类中保存String。
ps:用MouseReleased替换DragDone