我在ScrollPane中有一个非常大的StackPane(3000x2000)。我们的想法是将它用作一个大型的绘图板,用户可以在其中创建节点并拖动它们,以创建Mindmaps等。问题是拖放:如果scrollPane位于"起始位置",它的工作正常,因此Hvalue和Vvalue都是0.但是一旦你滚动了一下,DragEvent.getX()的值和.getY()返回是相对于窗格的可见部分,而不是它的整个大小。这意味着您无法正确拖放。我创建了一个测试类来说明问题而没有任何过时的代码:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class DragTestClass extends Application{
public static void problem(Circle circle, ScrollPane scrollPane, StackPane pane, DataFormat dataFormat){
circle.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
Dragboard db = circle.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.put(dataFormat,0); // normally, ID of node
db.setContent(content);
event.consume();
}
});
scrollPane.setOnDragDropped(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
if(db.hasContent(dataFormat) && db.getContent(dataFormat) instanceof Integer){
int index = (Integer) db.getContent(dataFormat);
Circle node = (Circle) pane.getChildren().get(index);
node.setManaged(false);
// this is the problematic part
node.setTranslateX(event.getX() - node.getCenterX());
node.setTranslateY(event.getY() - node.getCenterY());
event.setDropCompleted(true);
event.consume();
}
}
});
scrollPane.setOnDragOver(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
event.acceptTransferModes(TransferMode.ANY);
event.consume();
}
});
}
@Override
public void start(Stage primaryStage) throws Exception {
ScrollPane scrollPane = new ScrollPane();
StackPane pane = new StackPane();
DataFormat dataFormat = new DataFormat("DragDropFormat");
int width = 1000;
int height = 1000;
pane.setMinHeight(height);
pane.setMaxHeight(height);
pane.setMinWidth(width);
pane.setMaxWidth(width);
Circle circle = new Circle(50,50,20); // normally a StackPane
circle.setManaged(false);
pane.getChildren().add(circle);
pane.setAlignment(Pos.TOP_LEFT);
scrollPane.setContent(pane);
problem(circle, scrollPane, pane, dataFormat);
Scene scene = new Scene(scrollPane, 400, 400);
primaryStage.setTitle("Problem");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我的想法是在节点的转换中添加一些内容,例如scrollPane.getHvalue()* width,但这似乎并不起作用。也许我只是搜索了错误的关键字,但我还没有发现任何有用的信息,所以如果问题在其他地方得到解答,我很抱歉。在此先感谢您的帮助!
答案 0 :(得分:0)
我明白了!在StackPane上设置EventHandler(ScrollPane的内容,而不是ScrollPane本身)就可以了。显然,event.getX()返回的坐标是相对于具有EventHandler的节点。在这个例子中:
pane.setOnDragDropped...