gpt4 book ai didi

JavaFX - 拦截来自 "child"可平移 ScrollPane 的拖动事件并重定向到 "parent"ScrollPane

转载 作者:太空宇宙 更新时间:2023-11-04 13:55:29 36 4
gpt4 key购买 nike

我正在尝试从一个可平移的 ScrollPane(“子”)中“拦截”拖动事件,并将该事件重定向到另一个 ScrollPane(“父”)。

这是我这样做的尝试:

import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application
{
private final Image PARENT_IMAGE = new Image("http://www.tolkien.co.uk/file/IfbTdA8/5d04a105-e66b-4d9b-b218-928c691eb83d.jpg");
private final Image CHILD_IMAGE = new Image("http://knightly-slumber.com/worldofwarcraft/files/ScreenShot00019.jpg");

@Override
public void start(Stage stage) throws Exception
{
stage.setTitle("ScrollPane Sync");

// Set up the scene (two ScrollPanes, both pannable)
final ScrollPane parentScrollPane = new ScrollPane();
final ScrollPane childScrollPane = new ScrollPane();
parentScrollPane.setPrefSize(600, 400);
childScrollPane.setPrefSize(200, 200);
parentScrollPane.setContent(new ImageView(PARENT_IMAGE));
childScrollPane.setContent(new ImageView(CHILD_IMAGE));
parentScrollPane.setPannable(true);
childScrollPane.setPannable(true);
parentScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
parentScrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
childScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
childScrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
parentScrollPane.setCursor(Cursor.MOVE);
childScrollPane.setCursor(Cursor.MOVE);
VBox root = new VBox(parentScrollPane, childScrollPane);
root.setPrefSize(800, 600);

// Make childScrollPane sync with parentScrollPane's h and v-values
childScrollPane.hvalueProperty().bind(parentScrollPane.hvalueProperty());
childScrollPane.vvalueProperty().bind(parentScrollPane.vvalueProperty());

// Attempt to intercept drag events from childScrollPane and re-direct to parentScrollPane
childScrollPane.addEventFilter(MouseEvent.MOUSE_DRAGGED, event ->
{
// re-map x,y coords relative position from child to parent (as they are different sizes).
// In other words, if the drag event happened 40% of the way "across" (from the left) and 60%
// "down" (from the top) the child pane, then re-map those relative positions to absolute
// positions in terms of the parent pane (40% across and 60% down the parent pane).
double xRelative = event.getX() / childScrollPane.getViewportBounds().getWidth();
double xInParent = xRelative * parentScrollPane.getViewportBounds().getWidth();
double yRelative = event.getY() / childScrollPane.getViewportBounds().getHeight();
double yInParent = yRelative * parentScrollPane.getViewportBounds().getHeight();

Point2D screenCoords = parentScrollPane.localToScreen(xInParent, yInParent);

MouseEvent redirectedEvent = new MouseEvent(
parentScrollPane, root,
MouseEvent.MOUSE_DRAGGED, xInParent, yInParent,
screenCoords.getX(), screenCoords.getY(), event.getButton(), event.getClickCount(),
event.isShiftDown(), event.isControlDown(), event.isAltDown(), event.isMetaDown(),
event.isPrimaryButtonDown(), event.isMiddleButtonDown(), event.isSecondaryButtonDown(),
event.isSynthesized(), event.isPopupTrigger(), event.isStillSincePress(),
event.getPickResult()
);

MouseEvent.fireEvent(parentScrollPane, redirectedEvent);
event.consume();
});

Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}


public static void main(String[] args)
{
launch(args);
}
}

我有一个带有两个 ScrollPanes 的 VBox(舞台的根)。两个 ScrollPanes 都是可平移的。在本例中,我将顶部(和较大的)ScrollPane 指定为父 ScrollPane,将底部(和较小的)ScrollPane 指定为子 ScrollPane。我将子 ScrollPane 的 h 和 v 值绑定(bind)到父 ScrollPane,这样当在父 ScrollPane 中拖动/平移时,子 ScrollPane 也会移动。然后,我尝试为 MouseEvent.MOUSE_DRAGGED 事件添加事件过滤器,以便我们可以“拦截”父 ScrollPane 上的拖动事件。然后我尝试重新定向该事件并根据父 ScrollPane 重新转换它,然后触发这个新事件并使用旧事件。

目前,平移父 ScrollPane 会导致子 ScrollPane 也移动(这很好),但在子 ScrollPane 中拖动时不会发生任何事情(在这种情况下,我们希望两个 ScrollPane 都移动)。

有人可能会问:为什么不对两个 ScrollPanes 的 h 和 v 值使用双向绑定(bind)?我想避免这样做的原因是它破坏了我试图维持的父子关系。换句话说,我希望所有平移都“来自”并由父 ScrollPane 控制。

最佳答案

我设法通过这样做将子事件重定向到父滚动 Pane :

// Catch events on scrollPane's children
@FXML
public void press(MouseEvent event) {
ScrollPane sp = (ScrollPane) ((Node) event.getSource()).getParent().getParent().getParent().getParent();

PickResult pr = new PickResult(sp.getContent(), event.getSceneX(), event.getSceneY());
MouseEvent event2 = new MouseEvent(sp, sp.getContent(), event.getEventType(), event.getX(), event.getY(), event.getScreenX(), event.getScreenY(), event.getButton(), event.getClickCount(), event.isShiftDown(), event.isControlDown(), event.isAltDown(), event.isMetaDown(), event.isPrimaryButtonDown(), event.isMiddleButtonDown(), event.isSecondaryButtonDown(), event.isSynthesized(), event.isPopupTrigger(), event.isStillSincePress(), pr);
sp.getContent().fireEvent(event2);
}

@FXML
public void drag(MouseEvent event) {
ScrollPane sp = (ScrollPane) ((Node) event.getSource()).getParent().getParent().getParent().getParent();

PickResult pr = new PickResult(sp.getContent(), event.getSceneX(), event.getSceneY());
MouseEvent event2 = new MouseEvent(sp, sp.getContent(), event.getEventType(), event.getX(), event.getY(), event.getScreenX(), event.getScreenY(), event.getButton(), event.getClickCount(), event.isShiftDown(), event.isControlDown(), event.isAltDown(), event.isMetaDown(), event.isPrimaryButtonDown(), event.isMiddleButtonDown(), event.isSecondaryButtonDown(), event.isSynthesized(), event.isPopupTrigger(), event.isStillSincePress(), pr);
sp.getContent().fireEvent(event2);
}

// drag detected => cursor changes
@FXML
public void dragDetected(MouseEvent event) {
ScrollPane sp = (ScrollPane) ((Node) event.getSource()).getParent().getParent().getParent().getParent();

PickResult pr = new PickResult(sp.getContent(), event.getSceneX(), event.getSceneY());
MouseEvent event2 = new MouseEvent(sp, sp.getContent(), event.getEventType(), event.getX(), event.getY(), event.getScreenX(), event.getScreenY(), event.getButton(), event.getClickCount(), event.isShiftDown(), event.isControlDown(), event.isAltDown(), event.isMetaDown(), event.isPrimaryButtonDown(), event.isMiddleButtonDown(), event.isSecondaryButtonDown(), event.isSynthesized(), event.isPopupTrigger(), event.isStillSincePress(), pr);
sp.getContent().fireEvent(event2);
}

希望能有所帮助。

关于JavaFX - 拦截来自 "child"可平移 ScrollPane 的拖动事件并重定向到 "parent"ScrollPane,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29871861/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com