自定义平移处理程序 Javafx
Custom Panning Handler Javafx
您好,由于 scrollpane
的内置平移工具存在问题(运行缓慢且过渡成块而不是流畅)我正在尝试创建自定义平移处理程序。以下是我的尝试,但 if 语句无法正常工作。
mapScroll.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
startX = e.getX();
startY = e.getY();
});
mapScroll.addEventFilter(MouseEvent.MOUSE_DRAGGED, e -> {
endX = e.getX();
endY = e.getY();
Bounds viewBounds = mapScroll.getViewportBounds();
Bounds mapBounds = mapScroll.getBoundsInParent();
double xMin = viewBounds.getMinX();
double xMax = viewBounds.getMaxX();
double yMin = viewBounds.getMinY();
double yMax = viewBounds.getMaxY();
double startEndX = endX - startX;
double startEndY = endY - startY;
if(mapBounds.contains(xMin + startEndX, yMin + startEndY) && mapBounds.contains(xMin + startEndX, yMax + startEndY) && mapBounds.contains(xMax + startEndX, yMin + startEndY) && mapBounds.contains(xMax + startEndX, yMax + startEndY))
{
double fullWidth = mapScroll.getWidth();
double fullHeight = mapScroll.getHeight();
double hChange = startEndX/fullWidth;
double vChange = startEndY/fullHeight;
mapScroll.setHvalue(mapScroll.getHvalue() + hChange);
mapScroll.setVvalue(mapScroll.getVvalue() + vChange);
}
endX = startX;
endY = startY;
});
您从不在计算中使用内容的宽度。这意味着无论内容大小如何,您都必须将鼠标移动相同的距离才能从一侧滚动到另一侧到底部。内容是仅比视口大 10 个像素,还是内容是视口大小的 10 倍,对您的代码都没有影响。此外请注意
endX = startX;
endY = startY;
绝对没用,因为无论如何您都会在每次事件过滤器调用开始时覆盖这些值。您可能想以相反的方式完成作业。
您还可以按照与鼠标移动相同的方向移动滚动位置。但是,如果您希望鼠标位置相对于内容保持不变,则应向相反方向移动滚动位置。
这是一个示例(为简单起见删除了边界测试):
private double startX;
private double startY;
@Override
public void start(Stage primaryStage) {
ImageView image = new ImageView("https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/687px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg");
ScrollPane mapScroll = new ScrollPane(image);
Scene scene = new Scene(mapScroll, 400, 400);
mapScroll.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
startX = e.getX();
startY = e.getY();
});
mapScroll.addEventFilter(MouseEvent.MOUSE_DRAGGED, e -> {
double endX = e.getX();
double endY = e.getY();
Bounds viewBounds = mapScroll.getViewportBounds();
double startEndX = startX - endX;
double startEndY = startY - endY;
Bounds contentBounds = mapScroll.getContent().getLayoutBounds();
double hChange = startEndX / (contentBounds.getWidth() - viewBounds.getWidth());
double vChange = startEndY / (contentBounds.getHeight() - viewBounds.getHeight());
mapScroll.setHvalue(mapScroll.getHvalue() + hChange);
mapScroll.setVvalue(mapScroll.getVvalue() + vChange);
startX = endX;
startY = endY;
});
primaryStage.setScene(scene);
primaryStage.show();
}
您好,由于 scrollpane
的内置平移工具存在问题(运行缓慢且过渡成块而不是流畅)我正在尝试创建自定义平移处理程序。以下是我的尝试,但 if 语句无法正常工作。
mapScroll.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
startX = e.getX();
startY = e.getY();
});
mapScroll.addEventFilter(MouseEvent.MOUSE_DRAGGED, e -> {
endX = e.getX();
endY = e.getY();
Bounds viewBounds = mapScroll.getViewportBounds();
Bounds mapBounds = mapScroll.getBoundsInParent();
double xMin = viewBounds.getMinX();
double xMax = viewBounds.getMaxX();
double yMin = viewBounds.getMinY();
double yMax = viewBounds.getMaxY();
double startEndX = endX - startX;
double startEndY = endY - startY;
if(mapBounds.contains(xMin + startEndX, yMin + startEndY) && mapBounds.contains(xMin + startEndX, yMax + startEndY) && mapBounds.contains(xMax + startEndX, yMin + startEndY) && mapBounds.contains(xMax + startEndX, yMax + startEndY))
{
double fullWidth = mapScroll.getWidth();
double fullHeight = mapScroll.getHeight();
double hChange = startEndX/fullWidth;
double vChange = startEndY/fullHeight;
mapScroll.setHvalue(mapScroll.getHvalue() + hChange);
mapScroll.setVvalue(mapScroll.getVvalue() + vChange);
}
endX = startX;
endY = startY;
});
您从不在计算中使用内容的宽度。这意味着无论内容大小如何,您都必须将鼠标移动相同的距离才能从一侧滚动到另一侧到底部。内容是仅比视口大 10 个像素,还是内容是视口大小的 10 倍,对您的代码都没有影响。此外请注意
endX = startX;
endY = startY;
绝对没用,因为无论如何您都会在每次事件过滤器调用开始时覆盖这些值。您可能想以相反的方式完成作业。
您还可以按照与鼠标移动相同的方向移动滚动位置。但是,如果您希望鼠标位置相对于内容保持不变,则应向相反方向移动滚动位置。
这是一个示例(为简单起见删除了边界测试):
private double startX;
private double startY;
@Override
public void start(Stage primaryStage) {
ImageView image = new ImageView("https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/687px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg");
ScrollPane mapScroll = new ScrollPane(image);
Scene scene = new Scene(mapScroll, 400, 400);
mapScroll.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
startX = e.getX();
startY = e.getY();
});
mapScroll.addEventFilter(MouseEvent.MOUSE_DRAGGED, e -> {
double endX = e.getX();
double endY = e.getY();
Bounds viewBounds = mapScroll.getViewportBounds();
double startEndX = startX - endX;
double startEndY = startY - endY;
Bounds contentBounds = mapScroll.getContent().getLayoutBounds();
double hChange = startEndX / (contentBounds.getWidth() - viewBounds.getWidth());
double vChange = startEndY / (contentBounds.getHeight() - viewBounds.getHeight());
mapScroll.setHvalue(mapScroll.getHvalue() + hChange);
mapScroll.setVvalue(mapScroll.getVvalue() + vChange);
startX = endX;
startY = endY;
});
primaryStage.setScene(scene);
primaryStage.show();
}