Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX-截获来自";“儿童”;pannable ScrollPane并重定向到";“家长”;滚动窗格_Java_Javafx_Mouseevent_Javafx 8 - Fatal编程技术网

JavaFX-截获来自";“儿童”;pannable ScrollPane并重定向到";“家长”;滚动窗格

JavaFX-截获来自";“儿童”;pannable ScrollPane并重定向到";“家长”;滚动窗格,java,javafx,mouseevent,javafx-8,Java,Javafx,Mouseevent,Javafx 8,我试图从一个可平移滚动窗格(“子”)中“截取”拖动事件,并将该事件重新定向到另一个滚动窗格(“父”) 以下是我的尝试: import javafx.application.Application; import javafx.geometry.Point2D; import javafx.scene.Cursor; import javafx.scene.Scene; import javafx.scene.control.ScrollPane; import javafx.scene.imag

我试图从一个可平移滚动窗格(“子”)中“截取”拖动事件,并将该事件重新定向到另一个滚动窗格(“父”)

以下是我的尝试:

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);
    }
}
我有一个带有两个滚动窗格的VBox(舞台的根)。两个滚动窗格都是可平移的。在本例中,我将顶部(和更大的)滚动窗格指定为父滚动窗格,底部(和更小的)滚动窗格指定为子滚动窗格。我将子滚动窗格的h和v值绑定到父滚动窗格,这样当拖动/平移父滚动窗格时,子滚动窗格也会移动。然后我尝试为
MouseEvent.MOUSE\u拖动的
事件添加一个事件过滤器,以便我们可以在父滚动窗格上“截获”拖动事件。然后,我尝试重新定向该事件,并根据父滚动窗格重新投射它,然后触发这个新事件,并使用旧事件

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


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

我通过以下操作将子事件重定向到父滚动窗格:

// 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);
}
希望这会有帮助