How to send events from one Node to another Node

℡╲_俬逩灬. 提交于 2019-12-25 05:28:07

问题


I have a Pane which listens for the wheel mouse scroll; as well I have a scroll bar which automatically listens for the wheel mouse scroll. I would like to know how to send to scroll event captured by the Pane to the Scrollbar.

I can’t use a scroll pane because I need a custom implementation of the pane, I already tried to use a scroll pane and it did not cover my needs.

I tried to fire the event and other method but I just can get the event to be passed/propagated/sent to the scrollbar.

Thanks in advance

sample application:

package com.test;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class ScrollTest extends Application{

   @Override
   public void start(Stage primaryStage) throws Exception {


     final BorderPane root = new BorderPane();

     final Pane pane = new Pane();
     root.setCenter(pane);

     final ScrollBar scrollBar = new ScrollBar();
     root.setRight(scrollBar);


     pane.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>(){
        @Override
        public void handle(ScrollEvent arg0) {
           System.out.println("scrolling on the pane");

           Event.fireEvent(scrollBar, arg0);
//           scrollBar.getEventDispatcher().dispatchEvent(arg0, arg1)
        }
     });



     scrollBar.setOrientation(Orientation.VERTICAL);
     scrollBar.valueProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> ov, Number old_val, final Number new_val) {
           System.out.println("scrollBar.valueProperty() changed");
        }
     });


     primaryStage.setScene(new Scene(root, 600, 600));
     primaryStage.show();
   }

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

}

回答1:


Seems, you question is equal to the need of custom scroll pane implementation.

I think, a possible way - is to parse event, and make scroll bar change its value, when event comes (add listener on event on pane, parse whether scroll up or down, and use method increment or decrement of the scroll bar).

Also, we use some implementation for scroll event sending. Use this scratch for your implementation :

/**
 * Send ScrollEvent in the center of the control
 *
 * @param wrap Wrap, which will receive event
 * @param scrollX Number of pixels to scroll by x coordinate
 * @param scrollY Number of pixels to scroll by y coordinate
 */
protected static void sendScrollEvent(final Scene scene, Node node, double scrollX, double scrollY) {
    double x = node.getLayoutBounds().getWidth() / 4;
    double y = node.getLayoutBounds().getHeight() / 4;
    sendScrollEvent(scene, node, scrollX, scrollY, ScrollEvent.HorizontalTextScrollUnits.NONE, scrollX, ScrollEvent.VerticalTextScrollUnits.NONE, scrollY, x, y, node.getLayoutBounds().getMinX() + x, node.getLayoutBounds().getMinY() + y);
}

protected static void sendScrollEvent(final Scene scene, final Node node,
        double _scrollX, double _scrollY,
        ScrollEvent.HorizontalTextScrollUnits _scrollTextXUnits, double _scrollTextX,
        ScrollEvent.VerticalTextScrollUnits _scrollTextYUnits, double _scrollTextY,
        double _x, double _y,
        double _screenX, double _screenY) {
    //For 2.1.0 :
    //final ScrollEvent scrollEvent = ScrollEvent.impl_scrollEvent(_scrollX, _scrollY, _scrollTextXUnits, _scrollTextX, _scrollTextYUnits, _scrollTextY, _x, _y, _screenX, _screenY, false, false, false, false);
    //For 2.2.0 :
    //Interpretation: EventType<ScrollEvent> eventType, double _scrollX, double _scrollY, double _totalScrollX, double _totalScrollY, HorizontalTextScrollUnits _scrollTextXUnits, double _scrollTextX, VerticalTextScrollUnits _scrollTextYUnits, double _scrollTextY, int _touchPoints, double _x, double _y, double _screenX, double _screenY, boolean _shiftDown, boolean _controlDown, boolean _altDown, boolean _metaDown, boolean _direct, boolean _inertia)
    //For 8.0 before b64 and RT-9383
    //final ScrollEvent scrollEvent = new ScrollEvent.impl_scrollEvent(ScrollEvent.SCROLL, _scrollX, _scrollY, _scrollX, _scrollY, _scrollTextXUnits, _scrollTextX, _scrollTextYUnits, _scrollTextY, 0, _x, _y, _screenX, _screenY, false, false, false, false, false, false);

    //new ScrollEvent(EventType<ScrollEvent> eventType, 
    //double x, double y, double screenX, double screenY, 
    //boolean shiftDown, boolean controlDown, boolean altDown, boolean metaDown, 
    //boolean direct, boolean inertia, double deltaX, double deltaY, double gestureDeltaX, double gestureDeltaY, 
    //ScrollEvent.HorizontalTextScrollUnits textDeltaXUnits, double textDeltaX, 
    //ScrollEvent.VerticalTextScrollUnits textDeltaYUnits, double textDeltaY, int touchCount)
    final ScrollEvent scrollEvent = new ScrollEvent(ScrollEvent.SCROLL,
            _x, _y, _screenX, _screenY,
            false, false, false, false,
            false, false, _scrollX, _scrollY, 0, 0,
            _scrollTextXUnits, _scrollTextX,
            _scrollTextYUnits, _scrollTextY, 0, null /* PickResult?*/);

    Point2D pointOnScene = node.localToScene(node.getLayoutBounds().getWidth() / 4, node.getLayoutBounds().getHeight() / 4);
    final PickResultChooser result = new PickResultChooser();
    scene.getRoot().impl_pickNode(new PickRay(pointOnScene.getX(), pointOnScene.getY()), result);
    Node nodeToSendEvent = result.getIntersectedNode();
    nodeToSendEvent.fireEvent(scrollEvent);
}


来源:https://stackoverflow.com/questions/16341529/how-to-send-events-from-one-node-to-another-node

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!