问题
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