java - JavaFX - Intercept Drag Events from "child" pannable ScrollPane and redirect to "parent" ScrollPane -


i trying accomplish "intercepting" drag events 1 pannable scrollpane (the "child") , re-direct event scrollpane (the "parent").

here attempt @ doing so:

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 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 parentscrollpane's h , v-values         childscrollpane.hvalueproperty().bind(parentscrollpane.hvalueproperty());         childscrollpane.vvalueproperty().bind(parentscrollpane.vvalueproperty());          // attempt intercept drag events childscrollpane , re-direct parentscrollpane         childscrollpane.addeventfilter(mouseevent.mouse_dragged, event ->         {             // re-map x,y coords relative position child parent (as different sizes).              // in other words, if drag event happened 40% of way "across" (from left) , 60%              // "down" (from top) child pane, re-map relative positions absolute              // positions in terms of parent pane (40% across , 60% down 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);     } } 

i have vbox (the root of stage) 2 scrollpanes. both scrollpanes pannable. in case, designate top (and larger) scrollpane parent scrollpane, , bottom (and smaller) scrollpane child scrollpane. bind h , v-values of child scrollpane parent scrollpane, when 1 drags/pans in parent scrollpane, child scrollpane moves. attempt add event filter mouseevent.mouse_dragged events can "intercept" drag events on parent scrollpane. attempt re-direct event , re-cast in terms of parent scrollpane, , fire new event, , consume old one.

currently, panning parent scrollpane causes child scrollpane move (this good) nothing happens when dragging in child scrollpane (we want both scrollpane's move in case).

one might ask: why don't use bi-directional binding h , v-values 2 scrollpanes? reason want avoid doing breaks parent->child relationship trying maintain. in other words, want panning "come from" , controlled parent scrollpane.

i managed redirect children events parent scrollpane doing :

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

hope help.


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -