0

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);
   }

}
4

1 回答 1

1

看来,您的问题等于需要自定义滚动窗格实现。

我认为,一种可能的方法是解析事件,并在事件发生时使滚动条更改其值(在窗格上的事件上添加侦听器,解析向上或向下滚动,并使用滚动条的增量或减量方法)。

此外,我们使用一些实现来发送滚动事件。在您的实施中使用此划痕:

/**
 * 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);
}
于 2013-05-02T16:46:37.370 回答